React Context+LocalStorage购物车重复添加商品时其他商品变undefined求助
React Context + LocalStorage购物车:添加已有商品时其他商品变为undefined的解决方法
问题核心原因
在addToCart函数的map遍历逻辑中,仅对匹配ID的商品返回了新对象,未匹配的商品没有返回任何值,导致这些位置被填充为undefined,这就是其他商品“消失”的直接原因。
修复步骤及代码修正
1. 修复map函数的返回逻辑
在cartItem.map中,必须确保每个迭代都有返回值,未匹配的商品要返回原对象:
const updateCart = cartItem.map((product)=>{ if(product.id === Item.id){ return { ...product, quantity: product.quantity + quantity, } } // 必须返回原商品,否则会变成undefined return product; })
2. 修正总价与总数量的计算逻辑
原代码中setTotalPrice的计算逻辑错误,且直接依赖之前的状态容易出现不同步问题。建议每次购物车更新后,通过reduce重新计算总价和总数量:
// 添加这个useEffect,自动计算总价和总数量 useEffect(() => { const { totalQty, totalPrice } = cartItem.reduce((acc, item) => { return { totalQty: acc.totalQty + item.quantity, totalPrice: acc.totalPrice + item.price * item.quantity } }, { totalQty: 0, totalPrice: 0 }); setTotalQty(totalQty); setTotalPrice(totalPrice); }, [cartItem]);
3. 移除重复的LocalStorage初始化逻辑
useState的初始化函数已经从LocalStorage读取数据,无需再用额外的useEffect重复加载,否则会导致状态被覆盖:
// 删除这段重复的useEffect // useEffect(() => { // const json = localStorage.getItem('cartItem'); // const savedCart = JSON.parse(json); // if (savedCart) { // setCartItem(savedCart); // } // console.log("LocalStorage data:", savedCart); // }, []);
4. 避免直接修改原始数据源对象
原代码中Item.quantity = quantity会直接修改Items数组中的原始对象,改为直接构造新对象添加到购物车:
// 替换原来的else块逻辑 else{ setCartItem([...cartItem, { ...Item, quantity }]) }
5. 初始化totalPrice为0
避免总价初始为undefined导致计算异常:
const [totalPrice, setTotalPrice] = useState(0);
修正后的完整cartcontext.js代码
import { createContext, useContext, useState, useEffect } from "react"; const CartContext = createContext(); export const CartProvider =({children})=>{ const [cartItem, setCartItem] = useState(() => { const json = localStorage.getItem('cartItem'); return json ? JSON.parse(json) : []; }); const [qty, setQty] = useState(1); const [showCart, setShowCart] = useState(false); const [totalQty, setTotalQty] = useState(0); const [totalPrice, setTotalPrice] = useState(0); const increaseQty = ()=>{ setQty(prevQty => prevQty+1) } const decreaseQty = () =>{ setQty((prevQty)=>{ if(prevQty - 1< 1)return 1 return prevQty-1 }) } useEffect(() => { const json = JSON.stringify(cartItem); localStorage.setItem("cartItem", json); }, [cartItem]); // 自动计算总价和总数量 useEffect(() => { const { totalQty, totalPrice } = cartItem.reduce((acc, item) => { return { totalQty: acc.totalQty + item.quantity, totalPrice: acc.totalPrice + item.price * item.quantity } }, { totalQty: 0, totalPrice: 0 }); setTotalQty(totalQty); setTotalPrice(totalPrice); }, [cartItem]); const addToCart = (Item, quantity)=>{ const checkProduct = cartItem.find((product)=> product.id === Item.id) if(checkProduct){ const updateCart = cartItem.map((product)=>{ if(product.id === Item.id){ return{ ...product, quantity: product.quantity + quantity, } } return product; }) setCartItem(updateCart); } else{ setCartItem([...cartItem, { ...Item, quantity }]) } setQty(1); } const contextValue = { showCart, qty, totalPrice, increaseQty, decreaseQty, totalQty, addToCart, setShowCart, setCartItem, cartItem } return( <CartContext.Provider value ={contextValue}> {children} </CartContext.Provider> ) } export const useCartProvider = () => useContext(CartContext)
内容的提问来源于stack exchange,提问作者Guobin
相关产品推荐
相关产品推荐

