错误:不变失败:在路径“emailReducer.emails.0”中的调度之间检测到状态突变

Rod*_*ves 3 redux redux-toolkit

我收到有关改变状态的错误消息,但 Redux Toolkit 的目的是改变状态,所以我很困惑......

该错误来自,我将新电子邮件添加到调用usingaddNewEmail的数组中,第二个参数是常规字符串。prevEmailsuseSelector

import { createSlice } from "@reduxjs/toolkit";
import { AppThunk } from "./store";

const initialState = {
   emails: [],
};

export const emailSlice = createSlice({
   name: "email",
   initialState,
   reducers: {
      setEmails: (state, action: any) => {
         state.emails = action.payload;
      },
   },
});

export const { setEmails } = emailSlice.actions;

export const addNewEmail = (prevEmails: any, email: string): AppThunk => (
   dispatch
) => {
   const allEmails = prevEmails.push(email);
   dispatch(setEmails(allEmails));
};

export default emailSlice.reducer;

export const selectEmails = (state: any) => state.emailReducer.emails;
Run Code Online (Sandbox Code Playgroud)

Aur*_*yan 13

我也遇到了同样的错误,这不是您发送操作的方式。你所要做的就是在你的商店中传递这个中间件。

const store = configureStore({
          reducer,
          middleware: (getDefaultMiddleware) => getDefaultMiddleware({
               immutableCheck: false,
               serializableCheck: false,
          })
})
Run Code Online (Sandbox Code Playgroud)

  • 这可以帮助那些将现有的 redux 应用程序升级到 redux-toolkit 的人。 (6认同)
  • 像我这样的!我花了很长时间试图弄清楚为什么我会遇到不可变的错误,谢谢 immutableCheck: false 为我修复了。 (2认同)

mar*_*son 6

state.emails正如 @asaf-aviv 所说,真正的问题是你试图在减速器之外改变实际的内容:

   const allEmails = prevEmails.push(email);
   dispatch(setEmails(allEmails));
Run Code Online (Sandbox Code Playgroud)

第二个问题是概念性的。您应该将操作建模为“事件”,而不是“设置器”,并将尽可能多的逻辑放入减速器中。如果您遵循这些准则,那么这个问题一开始就不会发生。

此外,这甚至不需要是一个 thunk - 只需分派一个包含新电子邮件对象的操作即可。

处理这个问题的正确方法是:

export const emailSlice = createSlice({
   name: "email",
   initialState,
   reducers: {
      emailAdded: (state, action: PayloadAction<Email>) => {
         state.emails.push(action.payload)
      },
   },
});

export const { emailAdded } = emailSlice.actions;


// later
dispatch(emailAdded(newEmail));
Run Code Online (Sandbox Code Playgroud)