Redux 工具包历史 API 推送
Redux Toolkit history API push
在某些 react/redux 应用程序中,必须在调度某些操作后转换到路由。就我而言,我正是这种情况。让我向您展示一个状态切片的缩减器。
nextStep: (state, action) => {
const { steps } = state;
if (steps[state.currentTopNavStep][state.currentStep + 1]) {
state.currentStep++;
} else {
state.currentTopNavStep++;
state.currentStep = 0;
}
if (action.payload.history) {
const nextStep = steps[state.currentTopNavStep][state.currentStep];
const { gendersMatch, valuesExist } = nextStep;
let realNextStep;
if (
(valuesExist && valuesExist(state, fbObject)) ||
(gendersMatch && gendersMatch(state))
) {
state.currentStep++;
realNextStep = steps[state.currentTopNavStep][state.currentStep];
} else {
realNextStep = nextStep;
}
const newRoute = realNextStep.route;
action.payload.history.push(newRoute.path);
}
}
在最后一行,我想将一条新路由推送到历史记录中,我在调度此操作时将其作为有效负载获取。我想将 reducer 内部的逻辑移动到中间件中。 reduxToolkit 提供了 createAsyncThunk 函数。我想得到这样的东西:
const nextStep = createAsyncThunk(
'state/nextStep',
async (history, thunkAPI) => {
const { state } = thunkAPI.getState();
const { steps } = state;
if (steps[state.currentTopNavStep][state.currentStep + 1]) {
state.currentStep++;
} else {
state.currentTopNavStep++;
state.currentStep = 0;
}
if (history) {
const nextStep = steps[state.currentTopNavStep][state.currentStep];
const { gendersMatch, valuesExist } = nextStep;
let realNextStep;
if (
(valuesExist && valuesExist(state, fbObject)) ||
(gendersMatch && gendersMatch(state))
) {
state.currentStep++;
realNextStep = steps[state.currentTopNavStep][state.currentStep];
} else {
realNextStep = nextStep;
}
const newRoute = realNextStep.route;
const res = await history.push(newRoute.path);
return res; //this will be the action payload
}
}
);
然后在 extraReducers 中使用这个:
extraReducers: {
[nextStep.fullfilled]: (state, action) => {
//Here I face the problem, how to handle it in the reducer
return action.payload;
},
},
谁能帮我解决这个问题
问题是中间件不能改变状态。
你真的必须把这些分开做:
- reducer 改变状态
- 中间件有副作用
另外,createAsyncThunk
不是这里的正确工具。 cAT 的目的是让一个 thunk 发送一个“待定”动作,然后发送一个“已完成”或“拒绝”动作。你在这里似乎对这些没有任何用处。
您要么需要手动编写一个普通的 thunk,首先分派一个动作,在该分派获得新状态然后执行副作用之后,或者您将不得不自己编写一个中间件(这非常简单,因为好吧,文档中有相关示例)。
在某些 react/redux 应用程序中,必须在调度某些操作后转换到路由。就我而言,我正是这种情况。让我向您展示一个状态切片的缩减器。
nextStep: (state, action) => {
const { steps } = state;
if (steps[state.currentTopNavStep][state.currentStep + 1]) {
state.currentStep++;
} else {
state.currentTopNavStep++;
state.currentStep = 0;
}
if (action.payload.history) {
const nextStep = steps[state.currentTopNavStep][state.currentStep];
const { gendersMatch, valuesExist } = nextStep;
let realNextStep;
if (
(valuesExist && valuesExist(state, fbObject)) ||
(gendersMatch && gendersMatch(state))
) {
state.currentStep++;
realNextStep = steps[state.currentTopNavStep][state.currentStep];
} else {
realNextStep = nextStep;
}
const newRoute = realNextStep.route;
action.payload.history.push(newRoute.path);
}
}
在最后一行,我想将一条新路由推送到历史记录中,我在调度此操作时将其作为有效负载获取。我想将 reducer 内部的逻辑移动到中间件中。 reduxToolkit 提供了 createAsyncThunk 函数。我想得到这样的东西:
const nextStep = createAsyncThunk(
'state/nextStep',
async (history, thunkAPI) => {
const { state } = thunkAPI.getState();
const { steps } = state;
if (steps[state.currentTopNavStep][state.currentStep + 1]) {
state.currentStep++;
} else {
state.currentTopNavStep++;
state.currentStep = 0;
}
if (history) {
const nextStep = steps[state.currentTopNavStep][state.currentStep];
const { gendersMatch, valuesExist } = nextStep;
let realNextStep;
if (
(valuesExist && valuesExist(state, fbObject)) ||
(gendersMatch && gendersMatch(state))
) {
state.currentStep++;
realNextStep = steps[state.currentTopNavStep][state.currentStep];
} else {
realNextStep = nextStep;
}
const newRoute = realNextStep.route;
const res = await history.push(newRoute.path);
return res; //this will be the action payload
}
}
);
然后在 extraReducers 中使用这个:
extraReducers: {
[nextStep.fullfilled]: (state, action) => {
//Here I face the problem, how to handle it in the reducer
return action.payload;
},
},
谁能帮我解决这个问题
问题是中间件不能改变状态。
你真的必须把这些分开做:
- reducer 改变状态
- 中间件有副作用
另外,createAsyncThunk
不是这里的正确工具。 cAT 的目的是让一个 thunk 发送一个“待定”动作,然后发送一个“已完成”或“拒绝”动作。你在这里似乎对这些没有任何用处。
您要么需要手动编写一个普通的 thunk,首先分派一个动作,在该分派获得新状态然后执行副作用之后,或者您将不得不自己编写一个中间件(这非常简单,因为好吧,文档中有相关示例)。