问题描述
示例代码
import { AnyAction } from 'redux';
interface Props {
data: string;
}
export interface WatcherResult extends AnyAction {
payload: PROPS
}
type TacPopulate = () => WatcherResult;
const acPopulate: TacPopulate = () => ({
type: 'POPULATE',payload: {}
});
function* sagaWorker(
action: WatcherResult
): Generator<StrictEffect,WatcherResult,Props> {
return = {
data: 'hello world'
});
}
function* sagaWatcher() {
yield takeEvery('POPULATE',sagaWorker);
}
// trigger
dispatch({
type: 'POPULATE'
});
该方法正确分派,但reducer 没有收到新的payload。 似乎我总是必须像这样做一个额外的“yield put”,这似乎是多余的代码和膨胀,我必须通过单独的 reducer 方法接收。
function* sagaWorker(
action: WatcherResult
): Generator<StrictEffect,Props> {
yield put({
type: 'YET_ANOTHER_ACTIONTYPE',payload: {
data: 'hello world'
}
})
}
解决方法
听起来您的要求是更改现有操作。这不是 redux-saga 的工作方式。在您的示例中,您的减速器将收到两个操作:
group_id candidates_id score top_candidate
1 (a,b,c,g) (0,1,1) (a,c)
2 (d,e,h) (1,0) (e,h)
{type: "POPULATE"}
当传奇“采取”一个动作时,该动作仍会传递到商店。
如果你想停止一个动作并替换它,那么你需要自定义中间件。在这里,我们查找带有空 {type: "YET_ANOTHER_ACTIONTYPE",payload: {data: "hello world"}}
的“POPULATE”操作,并将其替换为带有数据的操作。
payload
我必须通过单独的减速器方法接收。
也许,并非总是如此。当您在没有数据的情况下调用 import { Middleware } from "redux";
export const replaceAction: Middleware = (store) => (next) => (action) => {
if (action.type === "POPULATE" && !action.payload) {
console.log("caught action");
const data = "hello world";
const replacedAction = {
...action,payload: { data }
};
return next(replacedAction);
} else return next(action);
};
时,您的减速器是否需要做任何事情?有时,“触发动作”用于在减速器中设置某种状态,例如 {type: "POPULATE"}
。其他时候你可以完全跳过它。
这似乎是多余的代码和膨胀
如果您不致力于 saga,那么将 thunk 与 createAsyncThunk 一起使用会更容易实现。
就您的 Typescript 类型而言,isLoading: true
创建的操作无效,因为 acPopulate
为空(也许您的实际代码中存在某些内容)。您需要对此进行更改,以便在没有有效负载的填充请求和包含数据的填充成功之间存在差异。
payload