如何将 args 从 sagaMiddleware 传递给 action watcher

How to pass args from sagaMiddleware to action watcher

我是 Sagas 的新手,以前是 redux-thunk 背景, 所以我不确定将参数传递给我的最终行动的最佳方式是什么。 我会感激某种 "For dummy answer"

问题是,我的 store.js 中有一些名为 session 的对象 我在 sagaMiddleware 中创建了这个会话,但是为了让我在 sagas 中的功能正常工作,我总是需要与这个对象进行交互。

那么,问题来了。 使用我当前的代码,如何传递一些 args(在这种情况下 "session" 到 sagas.js 中的最终操作)

store.js这里是"session"

sagaMiddleware.run(function* () {
    yield* saga1(session);
    yield* saga2(session);
  });

saga1.js

导出操作:

export default function* root() {
  yield [
    fork(watchAction1),
    fork(watchAction2),
  ];
}

动作观察者

function* watchMyAction() {
  yield takeEvery(actionTypes.SEND_EVENT, myAction);
}

动作

function* myAction(action) { // Here I want again the sesssion
  // Action.payload stuff, here I want my session arg from loadStore.js
}

有多种方法可以做你想做的事,选择一种取决于你的用例和偏好。

传法

最简单的方法就是将对象一直向下传递到 myAction saga。

yield* saga1(session)
...
fork(watchAction1, session)
...
yield takeEvery(actionTypes.SEND_EVENT, myAction, session)
...
function* myAction(session, action) {
    console.log(session);
}

如果您的 sagas 很少,或者如果您的 sagas 的结构是扁平的,那么您不必将它传递得太深,那么这是一个足够好的解决方案。

导入方式

另一种方法是导入会话对象。如果你需要先做一些初始化,你可以创建一个导出单例对象的文件,像这样:

// session.js
import Session from 'session-library';

const config = {foo: 'bar'};
export default new Session(config);

现在您可以在需要访问会话的任何地方导入此文件。您无需通过多个 files/sagas 就可以将其深入到您的传奇之一。但是,如果您需要替换会话对象,问题可能会有点多。

// action.js
import session from 'path/to/session';

function* myAction(action) {
    console.log(session);
}

上下文方法

第三种方法是使用setContext/getContext效果。这是我个人最喜欢的,因为它不依赖于模块系统,不需要任何特殊文件,并且您可以在需要的确切时刻请求访问 session 之类的对象 - 甚至是中途 saga 执行.

// store.js
const stuffYouWantToAccess = {session};
sagaMiddleware.run(function* (stuffYouWantToAccess) {
    yield setContext(stuffYouWantToAccess);
   ...
}, stuffYouWantToAccess);

// action.js

function* myAction(action) {
    const session = yield getContext('session');
    console.log(session);
}

它也不是完美的,因为上下文有点像全局变量,您需要使用字符串名称 ('session') 访问上下文值,这有时会成为问题(例如,当使用闭包编译器时或类型检查)。

所以选择你的毒药:)