React.js实现首页加购与结算页清空购物车的代码方案
React 购物车功能实现:Homepage 与 Checkout 组件改造
要实现跨组件的购物车功能,核心是共享购物车状态,这里用 React Context 来做全局状态管理,避免 props 层层传递,以下是具体改造步骤:
一、创建购物车全局状态上下文(CartContext)
新建 CartContext.js 文件,封装购物车的状态和操作方法:
import { createContext, useContext, useState } from 'react'; const CartContext = createContext(); export function CartProvider({ children }) { const [cartItems, setCartItems] = useState([]); // 添加商品到购物车:已存在则增加数量,否则新增商品 const addToCart = (item) => { setCartItems(prevItems => { const existingItem = prevItems.find(i => i.id === item.id); if (existingItem) { return prevItems.map(i => i.id === item.id ? {...i, quantity: i.quantity + 1} : i ); } else { return [...prevItems, {...item, quantity: 1}]; } }); }; // 清空购物车 const clearCart = () => { setCartItems([]); }; return ( <CartContext.Provider value={{ cartItems, addToCart, clearCart }}> {children} </CartContext.Provider> ); } // 自定义钩子,简化上下文调用 export function useCart() { return useContext(CartContext); }
然后在根组件(比如 App.js)中用 CartProvider 包裹 Home 和 Checkout,确保两者能访问购物车状态:
import { CartProvider } from './CartContext'; import Home from './Homepage'; import Checkout from './Checkout'; import { Routes, Route } from 'react-router-dom'; function App() { return ( <CartProvider> <Routes> <Route path="/" element={<Home />} /> <Route path="/checkout" element={<Checkout />} /> </Routes> </CartProvider> ); } export default App;
二、改造 Homepage.js(实现「加入购物车」功能)
引入购物车钩子,给按钮绑定添加逻辑,同时修正变量名冲突问题:
import { useState, useEffect } from 'react'; import { useCart } from './CartContext'; function Home() { const [data, setData] = useState([]); const { addToCart } = useCart(); useEffect(() => { fetch("/coffees").then((res) => { if (res.ok) { res.json().then((data) => setData(data)) } }); }, []) return ( <> <div className="box"> <div className="projo"> <h2>Welcome to Coffee-cafe</h2> </div> <div className="projects"> {data.map((item) =>{ // 把参数名从data改为item,避免和外层状态冲突 return( <div className="card" key={item.id}> {/* 添加key属性,消除React警告 */} <img className="avatar" src={item.coffee_image} alt={item.coffee_name}></img> <div className="card-content"> <h4><b>{item.coffee_name}</b></h4> <p id="desc">{item.description}</p> <p className="price">{item.price}</p> {/* 点击时将当前商品传入购物车方法 */} <button onClick={() => addToCart(item)} className="btn1" id="btn1">Add to Cart</button> </div> </div> ) })} </div> </div> </> ) } export default Home;
三、改造 Checkout.js(展示购物车商品+「清空购物车」功能)
引入购物车钩子,渲染商品列表、计算总价,绑定清空逻辑:
import { useCart } from './CartContext'; function Checkout() { const { cartItems, clearCart } = useCart(); // 计算购物车商品总价 const totalPrice = cartItems.reduce((total, item) => total + (item.price * item.quantity), 0); return ( <> <div className="section"> {/* 购物车为空时的提示 */} {cartItems.length === 0 ? ( <p>购物车是空的,快去挑选咖啡吧!</p> ) : ( <> {/* 遍历渲染购物车商品 */} {cartItems.map((item) => ( <div className="photo" key={item.id}> <img className="dp" src={item.coffee_image} alt={item.coffee_name}></img> <div className="info"> <h3>Coffee: {item.coffee_name}</h3> <p>Price: {item.price} x {item.quantity} = {item.price * item.quantity}</p> <p>Category: {item.category}</p> </div> </div> ))} {/* 总价展示 */} <div className="total-price"> <h4>总价: {totalPrice}</h4> </div> {/* 清空购物车按钮 */} <div className="check-out-btn"> <button className="delete" onClick={clearCart}>ClearCart</button> </div> </> )} </div> </> ) } export default Checkout;
内容的提问来源于stack exchange,提问作者Kelvin Matheka
相关产品推荐
相关产品推荐

