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

React购物车页面修改商品数量时报错求助

React购物车数量增减功能报错修复

问题场景

购物车页面点击商品数量的增减按钮时出现报错,以下是相关代码及修复方案:

Cart.js(购物车页面组件)

import React, { Fragment } from 'react';
import "./Cart.css";
import CartItemCard from "./CartItemCard";
import { useSelector, useDispatch } from 'react-redux'
import { addItemsToCart } from '../../action/cartAction';


const Cart = () => {

    const dispatch = useDispatch();
    const { cartItems } = useSelector((state) => state.cart);

    const increaseQuantity = (id, quantity, stock) => {
        const newQty = quantity + 1 ;
        if(stock <= quantity) {
            return;
        }
        dispatch(addItemsToCart(id, newQty));
    };

    const decreaseQuantity = (id, quantity) => {
        const newQty = quantity - 1 ;
        if (1 >= quantity) {
            return;
        }
        dispatch(addItemsToCart(id, newQty));
    };

    return (
        <Fragment>
            <div className="cartPage">
                <div className="cartHeader">
                    <p>Product</p>
                    <p>Quantity</p>
                    <p>Subtotal</p>
                </div>

                {cartItems.map((item) => (
                    <div className="cartContainer" key={item.product} >
                        <CartItemCard item={item}  />
                        <div className="cartInput">
                            <button onClick={() => decreaseQuantity(item.product, item.quantity)} > - </button>
                            <input type="number" readOnly value={item.quantity} />
                            <button onClick={() => increaseQuantity(item.product, item.quantity, item.stock)} > + </button>
                        </div>
                        <p className="cartSubtotal">{`$${item.price*item.quantity}`}</p>
                    </div>
                ))}

                <div className="cartGrossTotal">
                    <div></div>
                    <div className="cartGrossTotalBox">
                        <p>Gross Total</p>
                        <p>{`$600`}</p>
                    </div>
                    <div></div>
                    <div className="checkOutBtn">
                        <button>Check Out</button>
                    </div>
                </div>
            </div>
        </Fragment>
    );
};

export default Cart;

cartAction.js(购物车操作Action)

import {ADD_TO_CART} from "../constants/cartConstants";
import axios from "axios";


export const addItemsToCart = (id, quantity) => async (dispatch,getState) => {
    const { data } = await axios.get(`/api/v1/product/${id}`);
    
    dispatch({
        type: ADD_TO_CART,
        payload: {
            product: data.product._id,
            name: data.product.name,
            price: data.product.price,
            image: data.product.images[0].url,
            stock: data.product.Stock,
            quantity,
        },
    });

    localStorage.setItem("cartItems",JSON.stringify(getState().cart.cartItems)); 
};

错误核心:CartReducer.js

原代码中,当购物车已存在该商品时,map函数错误地返回布尔值true,导致购物车数组结构被破坏,引发渲染报错:

// 错误代码片段
if(isItemExist) {
    return {
        ...state,
        cartItems: state.cartItems.map((i) =>
        i.product === isItemExist.product ? true : i
        ),
    };
}

修复后的CartReducer.js

将map函数中返回的true替换为Action.payload里带更新数量的商品对象item:

import {ADD_TO_CART} from "../constants/cartConstants";

export const cartReducer = (state = { cartItems: [] }, action ) => {
    switch (action.type) {
        case ADD_TO_CART:
            const item = action.payload;
            const isItemExist = state.cartItems.find(
                (i) => i.product === item.product
            );

            if(isItemExist) {
                return {
                    ...state,
                    cartItems: state.cartItems.map((i) =>
                    // 替换为更新后的商品对象
                    i.product === isItemExist.product ? item : i
                    ),
                };
            } else {
                return{
                    ...state,
                    cartItems: [...state.cartItems, item],
                };
            }
        default:
            return state;
    }
};

Store.js(Redux Store配置)

import { createStore,combineReducers,applyMiddleware } from "redux";
import thunk from "redux-thunk";

import { composeWithDevTools } from "@redux-devtools/extension";
import { productDetailsReducer, producReducer } from "./reducers/productReducer";
import { forgotPasswordReducer, profileReducer, userReducer } from "./reducers/userReducer";
import { cartReducer } from "./reducers/cartReducer";


const reducer = combineReducers({
    products: producReducer,
    productDetails: productDetailsReducer,
    user: userReducer,
    profile: profileReducer,
    forgotPassword: forgotPasswordReducer,
    cart: cartReducer,
});

let initialState = {
    cart: {
        cartItems: localStorage.getItem("cartItems")
            ? JSON.parse(localStorage.getItem("cartItems"))
            : [],
    }
};

const middleware = [thunk]

const store = createStore(
    reducer,
    initialState,
    composeWithDevTools(applyMiddleware(...middleware))
);

export default store;

额外注意点

  1. 检查后端接口返回的库存字段是否为Stock(Action中使用的是data.product.Stock),如果后端返回的是小写stock,需要同步修改,避免库存判断失效。
  2. Cart.js中cartItems && cartItems.map(...)可以简化为cartItems.map(...),因为初始状态下cartItems是数组,不会为null或undefined。

内容的提问来源于stack exchange,提问作者Sayedul Karim

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 08:30:52