将所有 saga 动作包装在一个通用的生成器函数中

问题描述

我在我的应用程序中使用了 redux-sage,下面是我的代码

export default function* () {
    yield takeLatest(ActionTypes.VALIDATE_INPUT,checkForInputValidity);
    yield takeLatest(ActionTypes.ON_REFRESH,onRefresh);
    yield takeLatest(ActionTypes.ON_SUBMIT,onSubmit);
}

有没有办法确保在处理任何操作之前调用通用生成函数。例如, 每当我调度某个动作时,我都想更新 redux-state 中的变量。这在所有操作中都很常见。我在这里试图避免的是在每个动作处理程序中复制一些通用代码

解决方法

您可以使用 simple reducer function 跳过操作类型检查并跟踪所有操作,即返回当前时间戳:

export default () => + new Date()

,

您可以不带参数调用 take 或调用 '*' 以匹配所有操作,根据 docs

可能会变得棘手的部分(尽管仍然完全可行!)是获取生成器函数的正确顺序。通用生成器在其他生成器之前运行是否重要,或者如果它们全部异步运行是否可以? concurrencyfork vs spawnrunning tasks in parallel 上的文档可能会说明差异。

未经测试,但我认为这就是您想要的:

import {all,takeLatest,takeEvery } from "redux-saga/effects";

function* universal(action) {
  // do something
  // if dispatching anything here,make sure that the dispatched action doesn't get picked up again and create an infinite loop
}

export default function* () {
  // univeral generator is called with a blocking yield
  yield takeEvery( '*',universal);
  // run individual generators in parallel to each other
  yield all ([
    takeLatest(ActionTypes.VALIDATE_INPUT,checkForInputValidity),takeLatest(ActionTypes.ON_REFRESH,onRefresh),takeLatest(ActionTypes.ON_SUBMIT,onSubmit),]);
}

或者,您可以编写某种自定义中间件。