Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dispatch an action from a service unaware of Redux?

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)?

like image 947
dagatsoin Avatar asked Feb 15 '16 18:02

dagatsoin


People also ask

How do I dispatch actions in Redux functional component?

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.

How do I dispatch action from reducer?

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.

Is it possible to trigger a Redux action from outside a component?

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.

How do I dispatch a message to the Redux store?

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.

How to dispatch multiple actions in a single method in Redux?

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.

How to use Redux actions outside a React component?

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

What is mapdispatchtoprops in Redux?

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.


2 Answers

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:

  1. Make it a singleton (yup, not what you wanted, but it’s a valid option for client-only apps)
  2. Pass it down explicitly via props (can get tedious but it’s the most straightforward and explicit way)
  3. Pass it down implicitly via context (very easy but you will be dealing with an unstable API that is subject to change so it’s on your conscience)
like image 119
Dan Abramov Avatar answered Sep 22 '22 19:09

Dan Abramov


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);
like image 45
ZigGreen Avatar answered Sep 22 '22 19:09

ZigGreen