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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 12:06:00