redux-saga:在redux中间件环境外调用saga

Redux-saga: Calling a saga outside the redux middleware environment

redux 传奇的新手 - 我正在尝试弄清楚当我可以访问商店时如何在 redux 中间件环境之外调用传奇。

阅读 redux saga 文档后,我有两个选择,要么调用 store.runSaga,要么使用 redux-saga 提供的 runSaga 实用程序。

这就是我想要做的:

步骤:

  1. 创建了一个在调度成功操作之前暂停的 saga。

像这样:

      export function* loadDashboardSequenced() {

      try {
      // Take pauses until action received.
      //Wait for the user to be loaded
      const user_success = yield take('FETCH_USER_SUCCESS');
       // ....do other stuff....
        } catch(error) {
         yield put({type: 'FETCH_FAILED', error: error.message});
      }
  1. 现在我正在尝试通过 store.runSaga https://redux-saga.js.org/docs/api/ or runSaga https://redux-saga.js.org/docs/api/index.html#runsagaoptions-saga-args
  2. 调用传奇

与 store.runSaga 相比,使用 runSaga 有什么好处吗?我不确定此时应该使用哪一个。有 thoughts/suggestions 吗?谢谢!

编辑:关于使用 runSaga 的后续问题 https://redux-saga.js.org/docs/advanced/UsingRunSaga.html 这行是什么意思

        subscribe: ..., // this will be used to resolve take Effects

store.runSaga 方法用于启动商店的根传奇。它还期望 redux-saga 成为一个商店中间件:

export default function configureStore(initialState) {
  const sagaMiddleware = createSagaMiddleware()
  return {
    ...createStore(reducer, initialState, applyMiddleware(/* other middleware, */sagaMiddleware)),
    runSaga: sagaMiddleware.run
  }
}

const store = configureStore()
store.runSaga(rootSaga)

另一方面,runSaga 方法用于将 redux-saga 连接到非存储对象和接口,这是你很少做的事情。

总而言之,如果您需要 sagas puttake 方法来处理 redux 操作,那么您需要使用 redux-saga 作为存储中间件。

如果您有一个从 REST 检索数据的 saga API 然后将数据传递给 reducer ... 那么在没有 store 的情况下测试您的 saga 很有意义。

此外,我不喜欢 Beginner Tutorial 测试的一点是,我想测试完整的堆栈,从客户端到服务器。 "Beginner Tutorial" 中的测试无法对此进行测试,因为它们实际上并未获得 saga 执行的结果,仅获得 call/put 消息。

我会查看 The best way to test Redux Sagas 进行全面讨论,但这里有一个快速示例,总结了 Phil Herbert 的 post:

import { runSaga } from 'redux-saga'; // using runSaga to execute the saga
import { testMeSaga } from './sagas'; // the saga under test

test('test testMeSaga by running it', async () => {
    // 'recordSaga' is a utility function for running sagas, see it below.
    const result = await recordSaga(
        testMeSaga,
        { payload: 'your input to the saga' }
    );
    expect(result.length).toBe(1);    
    // add more checks here ...
});

// this is the utility function that wraps the running of the saga
async function recordSaga(saga, initialAction) {
    const dispatched = [];
    await runSaga(
        {
            dispatch: (action) => dispatched.push(action)
        },
        saga,
        initialAction
    ).done;

    return dispatched;
}