在 redux sagas 中使 takeEvery 以 action.meta 为条件?
Make takeEvery conditional on action.meta in redux sagas?
我有一个 redux-saga,我只想为某些 action.meta
值触发:
function* handleUpdateSomeStuff(action): Generator {
if (action.meta === "Special_Meta") {
// run some code
}
}
function* myConditionalSaga(): Generator {
yield takeEvery(
[ActionTypes.UPDATE_SOME_STUFF],
handleUpdateSomeStuff
);
}
function* itemSaga(): Generator {
yield all([
fork(myConditionalSaga),
// ... more sagas
]);
}
目前,我在handleUpdateSomeStuff
内检查action.meta
是否满足某个条件。但我觉得代码永远不应该走那么远。但是,我看不到 action
参数如何在 myConditionalSaga
中可用以在那里进行检查。我在想这样的事情:
function* myConditionalSaga(action): Generator {
if (action.meta === "Special_Meta") {
yield takeEvery(
[ActionTypes.UPDATE_SOME_STUFF],
handleUpdateSomeStuff
);
}
}
上面的代码块是比其他任何代码都多的元代码,因为尝试将参数传递给 myConditionalSaga
会在 fork
语句中给出 TS 错误 Argument of type '(action: any) => Generator<unknown, any, unknown>' is not assignable to parameter of type '{ context: unknown; fn: (this: unknown, ...args: any[]) => any; }'.
。
有没有办法阻止handleUpdateSomeStuff
根据动作的action.meta
被调用?我确实读过 , as well as the docs on takeEvery,但我正在努力理解如何将其应用到我的场景中以获得所需的结果。
欢迎在评论中提出意见:难道我连这个都不用担心吗?让函数调用到达 myConditionalSaga
并在那里处理 if
?
take
及其变体支持函数作为其第一个参数,而不是动作类型(或动作类型数组)。
所以你应该可以这样做:
function* handleUpdateSomeStuff(action): Generator {
// this runs only for when meta is "Special_Meta"
}
function* myConditionalSaga(): Generator {
yield takeEvery(action => {
return (
action.type === ActionTypes.UPDATE_SOME_STUFF &&
action.meta === "Special_Meta"
);
}, handleUpdateSomeStuff);
}
这样看起来有点“罗嗦”,但如果您需要更频繁地限制基于元参数的处理程序,您当然可以创建一些实用程序助手,例如:
const typeAndMeta = (type, meta) => action => action.type === type && action.meta === meta
yield takeEvery(typeAndMeta(ActionTypes.UPDATE_SOME_STUFF, 'Special_Meta'), saga);
甚至
const takeEveryByMeta = (type, meta, saga, ...args) => {
return takeEvery(action => action.type === type && action.meta === meta, saga, ...args);
}
yield takeEveryByMeta(ActionTypes.UPDATE_SOME_STUFF, 'Special_Meta', saga);
您可以轻松地扩展这些助手以支持 types/meta 值的数组。
我有一个 redux-saga,我只想为某些 action.meta
值触发:
function* handleUpdateSomeStuff(action): Generator {
if (action.meta === "Special_Meta") {
// run some code
}
}
function* myConditionalSaga(): Generator {
yield takeEvery(
[ActionTypes.UPDATE_SOME_STUFF],
handleUpdateSomeStuff
);
}
function* itemSaga(): Generator {
yield all([
fork(myConditionalSaga),
// ... more sagas
]);
}
目前,我在handleUpdateSomeStuff
内检查action.meta
是否满足某个条件。但我觉得代码永远不应该走那么远。但是,我看不到 action
参数如何在 myConditionalSaga
中可用以在那里进行检查。我在想这样的事情:
function* myConditionalSaga(action): Generator {
if (action.meta === "Special_Meta") {
yield takeEvery(
[ActionTypes.UPDATE_SOME_STUFF],
handleUpdateSomeStuff
);
}
}
上面的代码块是比其他任何代码都多的元代码,因为尝试将参数传递给 myConditionalSaga
会在 fork
语句中给出 TS 错误 Argument of type '(action: any) => Generator<unknown, any, unknown>' is not assignable to parameter of type '{ context: unknown; fn: (this: unknown, ...args: any[]) => any; }'.
。
有没有办法阻止handleUpdateSomeStuff
根据动作的action.meta
被调用?我确实读过
欢迎在评论中提出意见:难道我连这个都不用担心吗?让函数调用到达 myConditionalSaga
并在那里处理 if
?
take
及其变体支持函数作为其第一个参数,而不是动作类型(或动作类型数组)。
所以你应该可以这样做:
function* handleUpdateSomeStuff(action): Generator {
// this runs only for when meta is "Special_Meta"
}
function* myConditionalSaga(): Generator {
yield takeEvery(action => {
return (
action.type === ActionTypes.UPDATE_SOME_STUFF &&
action.meta === "Special_Meta"
);
}, handleUpdateSomeStuff);
}
这样看起来有点“罗嗦”,但如果您需要更频繁地限制基于元参数的处理程序,您当然可以创建一些实用程序助手,例如:
const typeAndMeta = (type, meta) => action => action.type === type && action.meta === meta
yield takeEvery(typeAndMeta(ActionTypes.UPDATE_SOME_STUFF, 'Special_Meta'), saga);
甚至
const takeEveryByMeta = (type, meta, saga, ...args) => {
return takeEvery(action => action.type === type && action.meta === meta, saga, ...args);
}
yield takeEveryByMeta(ActionTypes.UPDATE_SOME_STUFF, 'Special_Meta', saga);
您可以轻松地扩展这些助手以支持 types/meta 值的数组。