React电商项目购物车优化:实现同商品数量累加而非重复添加
解决方案
要实现重复商品合并为单一条目并显示数量,需要调整购物车数据结构和添加逻辑,具体修改如下:
1. 调整ShopContext中的状态与addItem函数
原代码中checkoutItems是纯商品数组,无法记录数量,我们需要把每个条目改成包含商品信息和数量的对象。修改后的ShopContext代码:
const [products, setProducts] = useState([]); // 调整结构:每个元素为 { product: 商品对象, quantity: 数量 } const [checkoutItems, setCheckoutItems] = useState([]); const addItem = (id) => { const targetProduct = products[id]; setCheckoutItems(prevItems => { // 检查是否已存在该商品(假设商品对象有唯一id字段) const existingItem = prevItems.find(item => item.product.id === targetProduct.id); if (existingItem) { // 已存在则更新数量 return prevItems.map(item => item.product.id === targetProduct.id ? { ...item, quantity: item.quantity + 1 } : item ); } else { // 不存在则新增条目,数量设为1 return [...prevItems, { product: targetProduct, quantity: 1 }]; } }); }; const values = { products, addItem, checkoutItems, }; return ( <ShopContext.Provider value={values}>{props.children}</ShopContext.Provider> );
注:如果你的商品用其他唯一标识(如sku)区分,替换代码中的
item.product.id即可。
2. 结算页渲染逻辑修改
原结算页直接序列化数组,现在需要遍历checkoutItems,显示商品信息和对应数量:
const Checkout = () => { const { checkoutItems } = useContext(ShopContext); return ( <div className="my-7 lg:max-w-7xl mx-auto font-Rubik items-center"> {checkoutItems.length === 0 ? ( <p>购物车为空</p> ) : ( <div> {checkoutItems.map((item, idx) => ( <div key={idx} className="border-b py-3"> <p>商品名称:{item.product.name}</p> <p>单价:{item.product.price}</p> <p>数量:{item.quantity}</p> <p>小计:{item.product.price * item.quantity}</p> </div> ))} </div> )} </div> ); };
3. 按钮代码无需修改
原按钮的点击逻辑保持不变,依然传递商品索引即可:
<button id={idx} className="bg-purple-400 px-4" onClick={(e) => addItem(e.target.id)}> + </button>
修改后,多次点击同一商品的"+"按钮时,不会生成重复条目,只会对应增加该商品的数量,结算页也能正确显示每个商品的数量和小计。
内容的提问来源于stack exchange,提问作者gnw
相关产品推荐
相关产品推荐

