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,首先分派一个动作,在该分派获得新状态然后执行副作用之后,或者您将不得不自己编写一个中间件(这非常简单,因为好吧,文档中有相关示例)。