React Context API场景下购物车商品去重更新数量及逐量移除实现方案
解决方案
1. 修改 CartReducer.js 逻辑
核心调整添加商品、减少数量的处理逻辑,解决重复新增条目、点减号直接删除商品的问题:
import {ADD_TO_CART, CHANGE_CART_QUANTITY, DECREASE, REMOVE_FROM_CART} from '../Types' export const CartReducer = (state, action) => { switch (action.type) { case ADD_TO_CART: { // 判断商品是否已在购物车 const existItem = state.cart.find(c => c.id === action.payload.id) if (existItem) { // 已存在则直接将数量+1,不新增条目 return { ...state, cart: state.cart.map(c => c.id === action.payload.id ? {...c, qty: c.qty + 1} : c) } } // 不存在则新增条目 return { ...state, cart: [...state.cart, { ...action.payload, qty : 1}] }; } case DECREASE: { const existItem = state.cart.find(c => c.id === action.payload.id) if (existItem.qty === 1) { // 数量为1时再点击减号才移除商品 return { ...state, cart: state.cart.filter(c => c.id !== action.payload.id) } } // 数量大于1时仅将数量-1 return { ...state, cart: state.cart.map(c => c.id === action.payload.id ? {...c, qty: c.qty - 1} : c) } } case REMOVE_FROM_CART: { // 保留原逻辑,用于商品详情页直接移除整个商品的需求 return { ...state, cart: state.cart.filter((c) => c.id !== action.payload.id) }; } default: return state } }
2. 修改 BasketItem.js 显示与交互逻辑
修正数量、总价显示错误,调整减号按钮的触发动作:
import React, { useContext } from 'react' import image from '../../assets/image.png' import plusButtonImage from '../../assets/vector+.png' import subtractButtonImage from '../../assets/vector.png' import { CartState } from '../../context/cart/CartContext' import { ADD_TO_CART, DECREASE, REMOVE_FROM_CART } from '../../context/Types' import CustomizedSelect from '../SelectInput' export const BasketItem = ({item}) => { const { state: { cart }, dispatch, } = CartState(); return ( <div className="basket-item"> <div className="title-div"> <span>{item.title}</span> </div> <div className="image-div"> <img style={{height: "100%", width: "100%"}} src={image}/> </div> <div className="price-div"> <span>£{item.price}</span> </div> <div className="basket-quantity-div"> {/* 减号按钮触发DECREASE动作,不再直接删除商品 */} <button onClick={() => dispatch({ type: DECREASE, payload: item, })} className="subtract-btn"> <img src={subtractButtonImage}/> </button> {/* 显示当前商品的购买数量,而非购物车总条目数 */} <span className="quantity-value"> {item.qty} </span> <button onClick={() => dispatch({ type: ADD_TO_CART, payload: item, })} className="add-btn"> <img src={plusButtonImage}/> </button> </div> <div className="total-div"> {/* 单条目总价=单价*购买数量,而非购物车总金额 */} £{item.price * item.qty} </div> </div> ) }
如果需要展示整个购物车的总金额,可在购物车列表的外层组件添加如下计算逻辑:
const cartTotal = state.cart.reduce((sum, item) => sum + item.price * item.qty, 0)
内容的提问来源于stack exchange,提问作者MicSt
相关产品推荐
相关产品推荐

