简体   繁体   中英

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

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)

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM