首页 > 解决方案 > 如何将 args 从 sagaMiddleware 传递给 action watcher

问题描述

我是 Sagas 的新手,曾经来自 redux-thunk 背景,所以我不确定将参数传递给我的最终操作的最佳方式是什么。我会欣赏某种“对于虚拟答案”

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

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

store.js 这里是“会话”

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
}

标签: reduxreact-reduxredux-saga

解决方案


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

传下去的方法

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

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

现在,您可以在需要访问会话的任何地方导入此文件。您无需通过多个文件/传奇将其传递给您的一个传奇。但是,如果您需要替换会话对象,则可能会出现更多问题。

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

所以选择你的毒药:)


推荐阅读