首页 > 解决方案 > Redux + Typescript -> 错误:不可草拟值上的 case reducer 不得返回未定义的 redux

问题描述

我正在尝试在我的 redux 应用程序中导入打字稿。我使用这样的 redux 工具包 createSlice 函数:

const slice = createSlice({
  name: sliceName,
  initialState,
  reducers: {
    updateMode(state: SliceState, action: PayloadAction<ModePayload>) {
      state = action.payload.mode;
    },
  },
});

当我调度 updateMode 操作时,我收到以下错误:

Error: A case reducer on a non-draftable value must not return undefined

但是我的 action.payload 定义明确,redux 工具包是最新的。它与我的代码有关,但我无法弄清楚......

我试图在 updateMode 中返回状态并且它可以工作,但是我收到一个 TypeScript 错误:

Type '(state: SliceState, action: { payload: ModePayload; type: string; }) => SliceState' is not assignable to type 'CaseReducer<"SHOW_LIST", { payload: any; type: string; }> | CaseReducerWithPrepare<"SHOW_LIST", PayloadAction<any, string, any, any>>'.
  Type '(state: SliceState, action: { payload: ModePayload; type: string; }) => SliceState' is not assignable to type 'CaseReducer<"SHOW_LIST", { payload: any; type: string; }>'.
    Type 'SliceState' is not assignable to type 'void | "SHOW_LIST"'.
      Type '"SHOW_SKILL"' is not assignable to type 'void | "SHOW_LIST"'

有人可以向我解释我做错了什么吗?

在我的完整代码下方:

import { createSlice, PayloadAction } from "@reduxjs/toolkit";

type SliceState = "SHOW_LIST" | "SHOW_SKILL";

let initialState: SliceState = "SHOW_LIST";

const sliceName = "mode";

interface ModePayload {
  mode: SliceState;
}

//--- Slice reducer ---

const modeSlice = createSlice({
  name: sliceName,
  initialState,
  reducers: {
    updateMode(state: SliceState, action: PayloadAction<ModePayload>) {
      return (state = action.payload.mode);
    },
  },
});
export const { updateMode } = modeSlice.actions;
export default modeSlice.reducer;

标签: javascripttypescriptreduxredux-toolkit

解决方案


我是 Redux 维护者和 Redux Toolkit 的创建者。

实际问题出在这一行:

state = action.payload.mode;

这实际上并没有完成任何有用的事情。Immer 通过跟踪现有值的突变state.someField = 123来工作,例如. 您编写的行仅将局部state变量更改为指向其他内容。

Immer 要求您要么返回一个全新的状态值,要么改变现有状态。那行代码也没有。相反,reducer 最终只返回undefined,因此错误。

如果你想完全替换现有的状态,你应该只做return action.payload.mode.

另外,作为旁注:如果initialState输入正确,则不必state为每个减速器提供类型,因为它会被推断出来。


推荐阅读