如何将args从sagaMiddleware传递到Action Watcher

时间:2018-09-22 01:18:32

标签: redux react-redux redux-saga

我是Sagas的新手,曾经来自Redux-thunk背景, 因此,我不确定将参数传递给最终操作的最佳方法是什么。 我会喜欢某种“虚假答案”

问题是,我的store.js中有一个名为 session 的对象 我在sagaMiddleware中创建了该会话,但是为了使我的功能在sagas中起作用,我始终需要与该对象进行交互。

所以,问题是。 使用我当前的代码,如何传递一些 args (在这种情况下,将“会话”传递给sagas.js中的最终操作)

store.js ,这里是“会话”

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

saga1.js

Expor操作:

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
}

1 个答案:

答案 0 :(得分:2)

有多种方法可以完成所需的工作,选择一种方法取决于您的用例和偏好。

向下传递方法

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

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

现在,您可以在需要访问会话的任何位置导入此文件。您无需将其传递到多个文件/传奇中,只需要将其传递到您的Sagas的最深处。但是,如果需要替换会话对象,可能会有点麻烦。

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

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

上下文方法

第三种方法是使用setContext/getContext效果。这是我个人的最爱,因为它不依赖于模块系统,不需要任何特殊文件,并且您可以在需要时立即请求访问session之类的对象,甚至在执行传奇时也可以

// 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')访问上下文值,这有时可能会出现问题(例如,使用闭包编译器或类型检查时) )。

所以选择你的毒药:)