Redux问题:已在购物车的商品无法更新数量,反而重复创建对象
修复Redux购物车重复添加商品创建新对象的问题
问题描述:将商品加入购物车后,添加另一件商品,再次添加第一件商品时,系统不会增加该商品的数量,而是为其创建一个新对象。
原Reducer代码
switch (action.type) { case actionTypes.ADD_TO_CART: const product = state.products.find((p) => p.id === action.payload.id); const inCart = state.cart.find((item) => item?.product.id === action.payload.id ? true : false ); if (inCart) { let check = false; state.cart.map((item, key) => { if ( item.product.id === action.payload.id && item.setVar === action.payload.setVar ) { state.cart[key].quantity++; check = true; } }); if (!check) { const newItem = { product: product, setVar: action.payload.setVar, quantity: 1, }; state.cart.push(newItem); } } else { const newItem = { product: product, setVar: action.payload.setVar, quantity: 1, }; state.cart.push(newItem); } return { ...state, }; }
问题分析
- 直接修改原state:Redux要求reducer必须是纯函数,不能直接修改原state对象(比如
state.cart[key].quantity++、state.cart.push()这类操作属于状态突变),会导致状态更新无法被正确追踪。 inCart判断逻辑不全:原代码只检查商品id是否存在于购物车,未同时匹配setVar属性,导致后续即使存在同id但不同规格的商品,也会进入错误分支。- 遍历逻辑冗余且不安全:用
map遍历却不使用返回值,反而直接修改原数组,不符合Redux的immutable更新原则。
修复后的代码
switch (action.type) { case actionTypes.ADD_TO_CART: const product = state.products.find((p) => p.id === action.payload.id); // 同时匹配商品id和setVar,精准判断是否已在购物车中 const existingItem = state.cart.find( (item) => item.product.id === action.payload.id && item.setVar === action.payload.setVar ); if (existingItem) { // 创建新购物车数组,对匹配项更新数量,其余项保持不变 const updatedCart = state.cart.map((item) => item.product.id === action.payload.id && item.setVar === action.payload.setVar ? { ...item, quantity: item.quantity + 1 } : item ); return { ...state, cart: updatedCart, }; } else { // 创建新购物车数组,添加新商品项 const newItem = { product: product, setVar: action.payload.setVar, quantity: 1, }; return { ...state, cart: [...state.cart, newItem], }; } }
关键改动说明
- 精准匹配条件:将购物车商品的判断改为同时检查
product.id和setVar,确保只有完全相同的商品(包含规格属性)才会被判定为已存在。 - Immutable状态更新:
- 商品已存在时,用
map创建新数组,对匹配项进行浅拷贝并更新数量,避免修改原数组。 - 商品不存在时,用扩展运算符
[...state.cart, newItem]创建新数组,完全遵循纯函数要求。
- 商品已存在时,用
- 简化逻辑:移除冗余的
check变量和分支,逻辑更清晰,同时避免了状态突变的风险。
内容的提问来源于stack exchange,提问作者jiwami
相关产品推荐
相关产品推荐

