如何从不知道 Redux 的服务中分派操作?

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

假设我有一个不知道 Redux 的地理定位服务,我这样配置它:

backgroundGeoLocation.configure(
  callback // will be called with an argument when the coordinates change
);

在不从单独的模块导出 store 并使用 store.dispatch()(因为这将是一个单例)的情况下,使服务回调分派 Redux 操作的最干净的方法是什么?

如果您想将一些值传递给 JavaScript 中的某段代码,您需要使用函数。
例如,

function createGeoLocationService(store) {
  let backgroundGeoLocation = new BackgroundGeoLocation()
  backgroundGeoLocation.configure(coordinates => {
    store.dispatch({ type: 'UPDATE_COORDINATES', coordinates })
  })
  return backgroundGeoLocation
}

现在,无论您在哪里创建商店,都可以创建该服务:

let store = createStore(reducer)
let backgroundGeoLocation = createGeoLocationService(store)

如果您需要在组件中访问它,您可以:

  1. 使其成为单例(是的,这不是您想要的,但它是仅客户端应用程序的有效选项)
  2. 通过 props 显式传递(可能会很乏味,但这是最直接和明确的方式)
  3. 通过上下文隐式传递它(非常简单,但你将处理一个 unstable API that is subject to change 所以这是你的良心)

如果你不想callbackFn知道store.dispatch那么你必须创建类似事件流Observable 来自 callbackFn。完成后,您只需将流映射到 store.dispatch 函数即可。

您可以自由使用任何库来创建流,但我建议 Rx

在这种方法中,您必须使用类似的东西:

var geoLocation$ = new Rx.Subject();
var newCoordinatesAction = coordinates => ({
    type: "YOUR_TUPE", 
    payload: coordinates 
});
geoLocation$.map(newCoordinatesAction).map(store.dispatch);
backgroundGeoLocation.configure(::geoLocation$.onNext);