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

React中实现点击加入购物车按钮添加商品至购物车页面的方案

解决方案:实现点击「ADD TO CART」添加商品到购物车功能

核心思路是在组件间共享购物车状态,让Product组件能触发添加动作,Cart组件能动态渲染购物车内的商品。下面分两种场景给出实现方式:


1. 跨组件场景:用React Context管理状态(推荐)

如果Product和Cart组件不在直接父子层级,用Context可以避免层层传递props的麻烦。

第一步:创建购物车Context

新建CartContext.js文件:

import { createContext, useContext, useState } from 'react';

const CartContext = createContext();

export function CartProvider({ children }) {
  const [cartItems, setCartItems] = useState([]);

  // 添加商品到购物车,支持重复商品累加数量
  const addToCart = (product) => {
    setCartItems(prevItems => {
      const existingItem = prevItems.find(item => item.title === product.title);
      if (existingItem) {
        return prevItems.map(item => 
          item.title === product.title 
            ? {...item, quantity: item.quantity + 1} 
            : item
        );
      } else {
        return [...prevItems, {...product, quantity: 1}];
      }
    });
  };

  return (
    <CartContext.Provider value={{ cartItems, addToCart }}>
      {children}
    </CartContext.Provider>
  );
}

// 自定义Hook,简化组件调用Context的代码
export function useCart() {
  return useContext(CartContext);
}

第二步:在根组件包裹CartProvider

比如在App.js中:

import { CartProvider } from './CartContext';
import { Product } from './Product';
import Cart from './Cart';

function App() {
  return (
    <CartProvider>
      {/* 这里放你的路由或组件结构,比如商品页面和购物车页面 */}
      <Product image="商品图片地址" image2="商品细节图地址" title="商品标题" price="89,90 €" />
      <Cart />
    </CartProvider>
  );
}

export default App;

第三步:修改Product组件,绑定添加事件

import './Product.css';
import { useCart } from './CartContext';

export function Product(props){
  const { addToCart } = useCart();

  const handleAddToCart = () => {
    // 传递当前商品的核心信息到购物车
    addToCart({
      image: props.image,
      title: props.title,
      price: props.price
    });
  };

  return (
      <>
        <div className="product-container">
            <div className="product-background">
                <img className='product-image' src={props.image} alt={props.title}></img>
                <img className='product-image2' src={props.image2} alt={`${props.title} 细节图`}></img>
            </div>
        </div>
        <div className='description-container'>
            <div className="product-description">
                    <div className='product-title'>{props.title}</div>
                    <div className='product-price'>{props.price}</div>
                    <div className='product-button'>
                      <button 
                        type="button" 
                        className="product-btn"
                        onClick={handleAddToCart}
                      >
                        ADD TO CART
                      </button>
                    </div>
            </div>
        </div>
      </> 
    )
}

第四步:修改Cart组件,动态渲染商品

import './Cart.css'
import { Header } from './Header'
import { Card } from './Catalog'
import { useCart } from './CartContext'

function Price() {
  const { cartItems } = useCart();
  
  // 计算购物车总价
  const calculateTotal = () => {
    return cartItems.reduce((total, item) => {
      // 处理价格格式,将"89,90 €"转为数字计算
      const price = parseFloat(item.price.replace(',', '.').replace(' €', ''));
      return total + price * item.quantity;
    }, 0).toFixed(2).replace('.', ',') + ' €';
  };

  return (
    <div className='price-cont'>
      <div className='price-cointainer'>
            <div className='total'>TOTAL</div>
            <div className='price'>{calculateTotal()}</div>
            <div className='checkout'>CHECKOUT</div>
      </div>
    </div>
  )
}


export default function Cart(){
  const { cartItems } = useCart();

  return (
    <>
       <Header />
       <div className='cart-container'>
           <div className='item-container'>
             {/* 遍历购物车商品,动态渲染Card */}
             {cartItems.map((item, index) => (
               <Card 
                 key={`${item.title}-${index}`} 
                 image={item.image} 
                 title={item.title} 
                 price={item.price}
                 quantity={item.quantity}
               />
             ))}
           </div>
       </div>
       <Price />
    </>
  );
}

2. 简单场景:父子组件状态提升

如果Product和Cart有共同的父组件,直接通过状态提升传递数据即可:

父组件(如App.js):

import { useState } from 'react';
import { Product } from './Product';
import Cart from './Cart';

function App() {
  const [cartItems, setCartItems] = useState([]);

  const addToCart = (product) => {
    setCartItems(prev => [...prev, product]);
  };

  return (
    <>
      <Product 
        image="商品图片地址" 
        image2="商品细节图地址" 
        title="商品标题" 
        price="89,90 €" 
        addToCart={addToCart} 
      />
      <Cart cartItems={cartItems} />
    </>
  );
}

修改Product组件:

import './Product.css';

export function Product(props){
  const handleAddToCart = () => {
    props.addToCart({
      image: props.image,
      title: props.title,
      price: props.price
    });
  };

  return (
      <>
        {/* 原有结构不变,仅修改按钮点击事件 */}
        <div className='product-button'>
          <button 
            type="button" 
            className="product-btn"
            onClick={handleAddToCart}
          >
            ADD TO CART
          </button>
        </div>
      </> 
    )
}

修改Cart组件:

export default function Cart({ cartItems }){
  return (
    <>
       <Header />
       <div className='cart-container'>
           <div className='item-container'>
             {cartItems.map((item, index) => (
               <Card 
                 key={index} 
                 image={item.image} 
                 title={item.title} 
                 price={item.price}
               />
             ))}
           </div>
       </div>
       <Price />
    </>
  );
}

注:如果Card组件需要显示商品数量,记得传递quantity属性并在组件内渲染。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 12:05:15