Say I have a geolocation service that is not aware of Redux and I configure it like this:
backgroundGeoLocation.configure(
callback // will be called with an argument when the coordinates change
);
What is the cleanest way to make the service callback dispatch a Redux action without exporting store
from a separate module and using store.dispatch()
(because this would be a singleton)?
There are two ways to dispatch actions from functional components: Using mapDispatachToProps function with connect higher order component, same as in class based components. Using useDispatch hook provided by react-redux . If you want to use this hook, then you need to import it from the react-redux package.
Dispatching an action within a reducer is an anti-pattern. Your reducer should be without side effects, simply digesting the action payload and returning a new state object. Adding listeners and dispatching actions within the reducer can lead to chained actions and other side effects.
If you need to dispatch actions from outside a React component, the same technique will work: import the store, then call store. dispatch() , passing the action you need to dispatch. It works the same as the dispatch function you get from props via react-redux's connect function.
The dispatch method is available on the store object. An action gets dispatched to trigger an update to the Redux store. 1 // MessageSender.js 2 import { sendMsg } from './actions'; 3 // ... 4 this.props.store.dispatch(sendMsg(msg)) 5 // ... The downside of the above approach is that our React component is aware of the app logic.
If we want to dispatch many actions in a single method, we can do that as shown below: To run many async instructions one after the other and also maintain readability of the code, we can dispatch an action that will then trigger a saga. We can use redux-saga library in the same way.
But the only limitation of both the methods is that they can’t be used outside a React component else Redux will yell at you like anything. 3. Dispatching actions directly using the redux store object This store has the actual dispatch method that redux provides. So if you want to dispatch actions outside React components you can simply do that by
The second argument to connect is the function mapDispatchToProps, which is a wrapper for all the action creators using the dispatch method and is passed to the component. From the official docs for connect, we can describe mapDispatchToProps this way: If an object is passed, each function inside it is assumed to be a Redux action creator.
If you want to pass some value to some piece of code in JavaScript, you need to use functions.
For example,
function createGeoLocationService(store) {
let backgroundGeoLocation = new BackgroundGeoLocation()
backgroundGeoLocation.configure(coordinates => {
store.dispatch({ type: 'UPDATE_COORDINATES', coordinates })
})
return backgroundGeoLocation
}
Now, wherever you create the store, create that service:
let store = createStore(reducer)
let backgroundGeoLocation = createGeoLocationService(store)
If you need to access it in the components, you can either:
If you don't want to callbackFn
be aware of store.dispatch
then you must create something like event stream or Observable from callbackFn
. And once you have done you simply map the stream to store.dispatch
function.
You're free to use any lib for creating streams but i recommend Rx
In that approach you'll must come with something like:
var geoLocation$ = new Rx.Subject();
var newCoordinatesAction = coordinates => ({
type: "YOUR_TUPE",
payload: coordinates
});
geoLocation$.map(newCoordinatesAction).map(store.dispatch);
backgroundGeoLocation.configure(::geoLocation$.onNext);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With