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

时间:2020-11-05 10:39:03

标签: redux redux-toolkit

我收到有关突变状态的错误消息,但是redux工具箱的建议是突变状态,所以我很困惑...

错误来自addNewEmail,在这里我使用prevEmails向调用useSelector的数组添加新电子邮件,第二个参数是常规字符串。

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;


2 个答案:

答案 0 :(得分:2)

就像@ asaf-aviv所说的那样,真正的问题是您试图在化简器之外对state.emails的实际内容进行突变:

   const allEmails = prevEmails.push(email);
   dispatch(setEmails(allEmails));

第二个问题是概念性的。您应该model actions as "events", not "setters"put as much logic as possible into reducers。如果您遵循这些准则,则首先不会发生此问题。

而且,这甚至不必太麻烦了-只需调度一个包含新电子邮件对象的操作即可。

正确的 处理方式是:

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));

答案 1 :(得分:1)

您要在分派动作之前先对状态进行修改,您可以在化简器内部进行修改,但不能在其外部进行修改。

您可以将prevEmails.push(email)更改为prevEmails.concat(email),这将返回一个新数组,您可以将该数组作为有效载荷发送出去。