You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Redux Store数组添加订单项时数据异常问题求助

问题分析与解决方案

问题描述

我正在开发一套收银系统,需要创建包含商品及对应售卖数量的订单列表,当前使用Redux Store进行状态管理。

遇到的问题:当触发ADDORDERITEM动作时,传入的action.order示例为{id: 1, name:"halve zolen", categoryId:1, price: 1.0},在该case中会将state.numberOfOrderItems赋值给newOrder.numberOfOrderItems。

单次添加商品时功能正常,但添加同一商品且输入不同数量时,最终订单数组中两个对象的数量均为最后一次输入的值,而预期应为两个不同的数量。检查赋值后的action.order是正确的,推测问题与使用state.numberOfOrderItems有关,想了解问题原因及如何获取其快照值不再被更新。

我的代码如下:

import {createStore} from 'redux';

const kassaReducer = (state = {orders: [], numberOfOrderItems: ""}, action) => {
    switch (action.type){
        case "ADDORDERITEM":            
            let newOrder = action.order;          
            newOrder.numberOfOrderItems = state.numberOfOrderItems;
            return {orders: [...state.orders, newOrder], numberOfOrderItems: ""};
        case "REMOVEORDERITEM":
            return {orders : state.orders.remove(state.orders.indexOf(action.order)), numberOfOrderItems: state.numberOfOrderItems};
        case "SETITEMNUMBER":
            return {orders : state.orders, numberOfOrderItems: state.numberOfOrderItems === "" ? action.numberOfOrderItems : (state.numberOfOrderItems + action.numberOfOrderItems)};
    }
    return state;
}

const store = createStore(kassaReducer);

export default store;

问题原因

核心问题是直接修改了action.order的引用,而非创建新对象。Redux要求action保持不可变性,但你这里将newOrder指向了action.order的同一个引用,后续如果复用该原始商品对象(比如组件中同一商品的实例),之前添加到orders数组里的条目会因为引用相同,被后续的修改操作覆盖数值。

另外,state.numberOfOrderItems本身是值类型,赋值时确实拿到了当前状态的快照,但由于所有订单条目共享同一个对象引用,最后一次赋值的数量会同步到所有引用该对象的订单条目中。

解决方案

  1. 创建独立的订单对象,避免共享引用:在ADDORDERITEM分支中,通过对象展开语法创建新对象,再附加数量属性,不直接修改原始action.order。
  2. 修正REMOVEORDERITEM的数组操作:JavaScript数组没有remove方法,改用filter创建新数组,符合Redux不可变更新原则。
  3. 统一数量的数值类型:将numberOfOrderItems初始值设为数字0,避免字符串拼接替代加法的问题。

修改后的代码:

import {createStore} from 'redux';

const kassaReducer = (state = {orders: [], numberOfOrderItems: 0}, action) => {
    switch (action.type){
        case "ADDORDERITEM":            
            // 基于原始商品对象创建新订单,独立引用
            const newOrder = {
                ...action.order,
                numberOfOrderItems: state.numberOfOrderItems
            };
            return {
                ...state,
                orders: [...state.orders, newOrder],
                numberOfOrderItems: 0 // 重置数量为初始值
            };
        case "REMOVEORDERITEM":
            // 过滤掉目标订单,返回新数组
            return {
                ...state,
                orders: state.orders.filter(item => item !== action.order)
            };
        case "SETITEMNUMBER":
            // 确保数量为数字类型,执行加法运算
            const newNumber = typeof state.numberOfOrderItems === 'number' 
                ? state.numberOfOrderItems + Number(action.numberOfOrderItems) 
                : Number(action.numberOfOrderItems);
            return {
                ...state,
                numberOfOrderItems: newNumber
            };
    }
    return state;
}

const store = createStore(kassaReducer);

export default store;

关键说明

  • 不可变性是Redux的核心原则,所有状态更新必须创建新对象/数组,不能直接修改原引用,这样才能保证每个订单条目独立,后续操作不会影响历史条目。
  • 将数量初始值设为数字0,避免字符串类型导致的运算逻辑错误。

内容的提问来源于stack exchange,提问作者Amber Akkermans

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 19:50:37