不可起草值的 case reducer 不得返回 undefined

Ben*_*min 4 reactjs redux react-redux redux-toolkit

我正在处理我的项目@reduxjs/toolkit并创建UserSlice如下。

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

export type UserState = User | null;

export const initialUserState: UserState = null;

const UserSlice = createSlice({
  name: "User",
  initialState: initialUserState,
  reducers: {
    receiveUser: (state: UserState, action: PayloadAction<UserState>) => {
      state = action.payload;
    },
    clearUser: (state: UserState, _action: PayloadAction<void>) => {
      state = null;
    },
    signIn: (
      _,
      _action: PayloadAction<{
        email: string;
        password: string;
      }>
    ) => {},
    signInWithToken: (_, _action: PayloadAction<void>) => {},
  },
});

export default UserSlice;

Run Code Online (Sandbox Code Playgroud)

signIn signInWithToken动作创建者只是为了在UserSaga模块中采取行动,所以他们什么都不做。

当我派遣signIn行动时,发生以下错误。

index.js:1 Error: A case reducer on a non-draftable value must not return undefined
    at createReducer.ts:163
    at Array.reduce (<anonymous>)
    at createReducer.ts:143
...
Run Code Online (Sandbox Code Playgroud)

这个代码片段模式在我的其他项目中工作正常,但这个项目。我无法弄清楚这个错误的原因,所以我问这个问题。我的代码中是否有任何错误?

Mel*_*hia 7

我相信您不会在所有减速器中返回状态,因为在使用箭头函数时,对象需要额外的圆括号:

  reducers: {
    receiveUser: (state: UserState, action: PayloadAction<UserState>) => ({
      state: action.payload;
    }),
    clearUser: (state: UserState, _action: PayloadAction<void>) => ({
      state : null;
    }),
    signIn: (
      _,
      _action: PayloadAction<{
        email: string;
        password: string;
      }>
    ) => ({}),
    signInWithToken: (_, _action: PayloadAction<void>) => ({}),
  },
Run Code Online (Sandbox Code Playgroud)


msm*_*ens 6

Redux ToolkitcreateReducer()允许编写直接改变 state 的reducer 。这是通过使用produce来自Immer库的 reducer 调用来实现的。

但是,当 Immer 不能“起草”当前状态时,reducer 调用不会被包装,produce原始值就是这种情况,包括null

} else if (!isDraftable(previousState)) {
  // If state is not draftable (ex: a primitive, such as 0), we want to directly
  // return the caseReducer func and not wrap it with produce.
  const result = caseReducer(previousState as any, action)

  if (typeof result === 'undefined') {
    throw Error(
      'A case reducer on a non-draftable value must not return undefined'
    )
  }

  return result
}
Run Code Online (Sandbox Code Playgroud)

因为您的初始用户状态是null,所以您必须从receiveUser()减速器返回新状态。

  • 天哪,这是顶级解释,它也解决了我的问题。我使用了`createSlice({initialState:“lol”})`,但“lol”是一个原始字符串,所以我必须将其更改为“createSlice({initialState:{value:“lol”}})”。 (2认同)