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;
额外注意点
- 检查后端接口返回的库存字段是否为
Stock(Action中使用的是data.product.Stock),如果后端返回的是小写stock,需要同步修改,避免库存判断失效。 Cart.js中cartItems && cartItems.map(...)可以简化为cartItems.map(...),因为初始状态下cartItems是数组,不会为null或undefined。
内容的提问来源于stack exchange,提问作者Sayedul Karim
相关产品推荐
相关产品推荐

