使用Redux Toolkit向数组添加对象时被替换的问题解决
问题:Redux Toolkit中数组添加对象异常,结构错误且对象未正确追加
我希望通过Redux Toolkit将对象存储到数组中,但出现新对象未被正常添加、甚至数组结构异常的情况。尝试过state.warenkorb.push(action.payload)但没生效,当前代码使用state.warenkorb.push([...state.warenkorb, action.payload]),调试时发现数组变成嵌套结构,请问如何修正?
代码示例
import { createSlice } from "@reduxjs/toolkit"; const initialState = { warenkorb: [], preis: 0, bewertung: 0, }; export const produktSlice = createSlice({ name: "produkt", initialState, reducers: { hinzufügen: (state, action) => { // 尝试过但未生效 // state.warenkorb.push(action.payload); // state.warenkorb.push([...state.warenkorb, action.payload]); state.preis += action.payload.preis * action.payload.anzahl; }, entfernen: (state, action) => { if (state.warenkorb.includes(action.payload)) { state.warenkorb.splice( state.warenkorb.findIndex((id) => id === action.payload), 1 ); } }, bewerten: (state, action) => { state.bewertung = action.payload.bewertung; }, }, }); export const { hinzufügen, entfernen, bewerten } = produktSlice.actions; export default produktSlice.reducer;
问题原因分析
- 数组结构异常的直接原因:
state.warenkorb.push([...state.warenkorb, action.payload])这行代码错误地将「原数组+新对象组成的新数组」作为单个元素push到原数组中,导致数组嵌套。比如第一次调用后数组是[obj1],第二次调用就变成[obj1, [obj1, obj2]],完全打乱了结构。 push(action.payload)未生效的可能原因:Redux Toolkit基于Immer实现,允许直接对state进行mutate操作(如push、splice),Immer会自动将其转换为不可变更新,所以这行代码本身是有效的。之前未生效大概率是调试时action触发逻辑有问题,或是传入的payload对象存在引用重复等情况。
修正方案
1. 修复添加对象的逻辑
将hinzufügen reducer中的push代码改为直接添加单个对象:
hinzufügen: (state, action) => { // 直接将payload对象追加到数组末尾 state.warenkorb.push(action.payload); state.preis += action.payload.preis * action.payload.anzahl; }
2. 修复移除对象的逻辑(可选但必要)
原entfernen reducer中,includes(action.payload)是基于对象引用判断是否存在,若action传入的是新创建的对象(引用不同),会导致判断失效。建议根据对象的唯一标识(如id)来查找和移除:
entfernen: (state, action) => { // 假设每个产品对象有唯一id属性,根据id查找索引 const targetIndex = state.warenkorb.findIndex(item => item.id === action.payload.id); if (targetIndex !== -1) { // 移除前先扣除对应总价 state.preis -= state.warenkorb[targetIndex].preis * state.warenkorb[targetIndex].anzahl; state.warenkorb.splice(targetIndex, 1); } }
内容的提问来源于stack exchange,提问作者Captai-N
相关产品推荐
相关产品推荐

