#redux #redux-toolkit
#сокращение #redux-toolkit
Вопрос:
Я получаю это сообщение об ошибке об изменении состояния, но целью Redux Toolkit является изменение состояния, поэтому я в замешательстве…
Ошибка возникает из addNewEmail
-за того, что я добавляю новые электронные письма в массив, вызывающий prevEmails
using 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;
Ответ №1:
Я также получал ту же ошибку, это не то, как вы выполняете действие. Все, что вам нужно, это передать это промежуточное ПО в вашем хранилище.
const store = configureStore({
reducer,
middleware: (getDefaultMiddleware) => getDefaultMiddleware({
immutableCheck: false,
serializableCheck: false,
})
})
Комментарии:
1. Это может помочь людям, которые обновляют свое существующее приложение redux до redux-toolkit.
2. Как я! Я потратил много времени, пытаясь понять, почему я получаю неизменяемую ошибку, спасибо immutableCheck: false исправлено для меня.
3. Спасатель жизни. Это именно то, что нужно проекту. Спасибо!
Ответ №2:
Как сказал @asaf-aviv, реальная проблема заключается в том, что вы пытаетесь изменить то, что есть на самом деле state.emails
, за пределами редуктора:
const allEmails = prevEmails.push(email);
dispatch(setEmails(allEmails));
Вторая проблема носит концептуальный характер. Вы должны моделировать действия как «события», а не «установщики», и вкладывать как можно больше логики в редукторы. Если вы будете следовать этим рекомендациям, эта проблема не возникнет в первую очередь.
Кроме того, это даже не обязательно должно быть ошибкой — просто отправьте действие, содержащее новый объект электронной почты.
Правильный способ справиться с этим:
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));
Ответ №3:
Вы изменяете состояние перед отправкой действия, вы можете выполнять мутации внутри редуктора, но не за его пределами.
Вы можете изменить, prevEmails.push(email)
чтобы prevEmails.concat(email)
вернуть новый массив, который затем можно отправить в качестве полезной нагрузки.