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

React跨组件传值问题:如何在Cart页面展示购物车商品?

购物车跨页面数据共享解决方案

问题根源

当前购物车数据cartProducts仅存储在Products组件的本地状态中,而Products和Cart是路由切换的独立组件,彼此状态完全隔离,因此Cart页面的CartItems组件无法获取到已添加的购物车数据。

解决方案:使用React Context实现全局状态管理

1. 创建CartContext文件

新建CartContext.jsx,封装购物车的状态和操作方法:

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.id === product.id);
      if (existingItem) {
        return prevItems.map(item => 
          item.id === product.id 
            ? {...item, quantity: item.quantity + 1} 
            : item
        );
      }
      return [...prevItems, {...product, quantity: 1}];
    });
  };

  // 修改商品数量
  const updateQuantity = (productId, change) => {
    setCartItems(prevItems => 
      prevItems.map(item => {
        if (item.id === productId) {
          const newQuantity = item.quantity + change;
          return newQuantity > 0 ? {...item, quantity: newQuantity} : null;
        }
        return item;
      }).filter(item => item !== null)
    );
  };

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

export function useCart() {
  return useContext(CartContext);
}

2. 在根组件中包裹CartProvider

修改Main.jsx,用CartProvider包裹整个路由组件:

import React from 'react'
import ReactDOM from 'react-dom/client'
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import App from './App.jsx'
import Cart from './Cart.jsx'
import { Products } from './Products.jsx'
import { CartProvider } from './CartContext.jsx';

const router = createBrowserRouter([
  {
    path: "/",
    element: <App />,
  },
  {
    path: "/App",
    element: <App />,
  },
  {
    path: "/products",
    element: <Products />,
  },
  {
    path: "/cart",
    element: <Cart />,
  },
]);

ReactDOM.createRoot(document.getElementById("root")).render(
  <React.StrictMode>
    <CartProvider>
      <RouterProvider router={router} />
    </CartProvider>
  </React.StrictMode>
);

3. 修改Products组件,使用全局状态

更新Products.jsx,移除本地购物车状态,改用全局Context:

import { useState, useEffect } from 'react'
import './Products.css'
import NavBar from './NavBar.jsx'
import { useCart } from './CartContext.jsx';

function CartItems({ products, updateQuantity }) {
  if (!products || products.length === 0) {
    return (
      <>
        <h2>Cart is Empty</h2>
      </>
    )
  } else {
    return (
      <div id="cartItemList">
        {products.map(product => (
          <div className="cartItem" key={product.id}>
            <img src={product.image} alt={product.title} />
            <p>{product.title}</p>
            <p>{product.description}</p>
            <p>${product.price}</p>
            <div>
              <button onClick={() => updateQuantity(product.id, -1)}>-</button>
              <p>{product.quantity}</p>
              <button onClick={() => updateQuantity(product.id, 1)}>+</button>
            </div>
          </div>
        ))}
      </div>
    )
  }
}

function Products() {
  const [data, setData] = useState([]);
  const { cartItems, addToCart } = useCart();

  useEffect(() => {
    fetch('https://fakestoreapi.com/products?limit=4')
      .then(response => response.json())
      .then((data) => setData(data))
      .catch((error) => console.error(error));
  }, []);

  return (
    <>
      <NavBar />
      <div id="productsContainer">
        {data.map(product => (
          <div className="productBoxes" key={product.id}>
            <img className="productImg" src={product.image} alt={product.title} />
            <h1>{product.title}</h1>
            <p>{product.description}</p>
            <p>${product.price}</p>
            <button onClick={() => addToCart(product)} className="productCheck" id="productButton">Add to Cart</button>
          </div>
        ))}
        <CartItems products={cartItems} updateQuantity={useCart().updateQuantity} />
      </div>
    </>
  );
}

export { Products, CartItems };

4. 修改Cart组件,获取全局购物车数据

更新Cart.jsx,通过Context获取购物车数据:

import './Cart.css'
import NavBar from './NavBar.jsx'
import { CartItems } from './Products.jsx'
import { useCart } from './CartContext.jsx';

function Cart() {
  const { cartItems, updateQuantity } = useCart();

  return (
    <>
      <NavBar />
      <CartItems products={cartItems} updateQuantity={updateQuantity} />
    </>
  );
}

export default Cart;

额外优化说明

  • 拆分CartItems到独立文件(如CartItems.jsx)可进一步优化代码结构
  • 已实现重复商品数量累加逻辑,避免购物车出现重复条目
  • 修复了原代码中所有商品共享同一数量的问题,现在每个商品拥有独立数量

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 17:35:14