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

如何在ReactJS中修改购物车JSON结构,添加cart_id并替换索引键

调整React购物车数据结构以匹配Commerce.js格式

当前购物车数据为数组格式:

[
  {data: "ids", description: "An apple iPhone 8", id: 2, image: "/images/3.jpg", name: "iPhone 8", price: 100, qty: 1},
  {name: 'iPhone 7 +', description: 'An apple iPhone 7 plus', image: '/images/2.jpg', price: 120, id: 1, …}
]

需修改为Commerce.js兼容的对象结构:

{
  cart_id: "KLIN_321xxxxxxxxx", // 自定义生成的唯一ID
  line_items: [
    {data: "ids", description: "An apple iPhone 8", id: 2, image: "/images/3.jpg", name: "iPhone 8", price: 100, qty: 1},
    {name: 'iPhone 7 +', description: 'An apple iPhone 7 plus', image: '/images/2.jpg', price: 120, id: 1, …}
  ]
}

1. 修改App.js中的购物车状态及操作逻辑

将购物车从数组改为对象结构,抽离ID生成函数,同步更新所有购物车操作函数:

import React from 'react';
import { Navbar, Products, Cart, Checkout } from './components';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
import { CssBaseline } from '@material-ui/core';
import { products } from './components/Products/Product/ProductData';
import { useState } from 'react';

// 生成自定义cart_id
const generateCartId = () => {
  const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890".split("");
  let token = [];
  for (let i=0; i<12; i++) {
    const j = Math.floor(Math.random() * chars.length);
    token.push(chars[j]);
  }
  return `KLIN_321${token.join("")}`;
};

const App = () => {
  // 初始化符合Commerce.js格式的购物车对象
  const [cart, setCart] = useState({
    cart_id: generateCartId(),
    line_items: []
  });
  const [order, setOrder] = useState({});
  const [errorMessage, setErrorMessage] = useState({});

  const onAdd = (product) => {
    const exist = cart.line_items.find((x) => x.id === product.id);
    if (exist) {
      setCart({
        ...cart,
        line_items: cart.line_items.map((x) =>
          x.id === product.id ? { ...exist, qty: exist.qty + 1 } : x
        )
      });
    } else {
      setCart({
        ...cart,
        line_items: [...cart.line_items, { ...product, qty: 1 }]
      });
    }
  };

  const onRemove = (product) => {
    const exist = cart.line_items.find((x) => x.id === product.id);
    if (exist.qty === 1) {
      setCart({
        ...cart,
        line_items: cart.line_items.filter((x) => x.id !== product.id)
      });
    } else {
      setCart({
        ...cart,
        line_items: cart.line_items.map((x) =>
          x.id === product.id ? { ...exist, qty: exist.qty - 1 } : x
        )
      });
    }
  };

  const cartRemove = (product) => {
    setCart({
      ...cart,
      line_items: cart.line_items.filter((x) => x.id !== product.id)
    });
  };

  const cartEmpty = () => {
    // 清空商品时保留原有cart_id,如需重置可替换为generateCartId()
    setCart({
      ...cart,
      line_items: []
    });
  };

  const handleCaptureCheckout = (newOrder) => {
    try {
      setOrder(newOrder);
      cartEmpty();
    } catch (error) {
      setErrorMessage(error.message);
    }
  };

  return (
    <Router>
      <div>
        <CssBaseline />
        {/* 从line_items数组获取购物车数量 */}
        <Navbar countCartItems={cart.line_items.length}/>
        <Switch>
          <Route exact path="/">
            <Products onAdd={onAdd} products={products} />
          </Route>
          <Route path="/cart">
            <Cart 
              cartEmpty={cartEmpty} 
              cartRemove={cartRemove} 
              onAdd={onAdd} 
              cart={cart} 
              onRemove={onRemove} 
            />
          </Route>
          <Route path="/checkout">
            <Checkout 
              cart={cart} 
              order={order} 
              error={errorMessage} 
              onCaptureCheckout={handleCaptureCheckout} 
            />
          </Route>
        </Switch>
      </div>
    </Router>
  );
};

export default App;

2. 修改Cart.js组件适配新结构

更新组件内的购物车数据引用,移除无效逻辑:

import React from 'react'
import { Container, Typography, Button, Grid } from '@material-ui/core';
import CartItems from './CartItems/CartItems';
import useStyles from './styles';
import { Link } from 'react-router-dom';

const Cart = ({ cart, onAdd, onRemove, cartRemove, cartEmpty }) => {
    const classes = useStyles();
    console.log(cart); // 输出符合Commerce.js格式的购物车对象
    // 基于line_items计算商品总价
    const itemsPrice = cart.line_items.reduce((a, c) => a + c.qty * c.price, 0);
    const totalPrice = itemsPrice;

    return (
        <Container>
          <div className={classes.toolbar} />
          <Typography className={classes.title} variant="h3" gutterBottom>Your Shopping Cart</Typography>
          {/* 判断line_items是否为空 */}
          {cart.line_items.length === 0 && 
          <Typography variant="subtitle1">You have no items in your shopping cart,
            <Link className={classes.link} to="/">start adding some</Link>!
          </Typography>}
          <>
            <Grid container spacing={3}>
              {/* 遍历line_items渲染商品 */}
              {cart.line_items.map((item) => (
                <Grid item xs={12} sm={4} key={item.id}>
                  <CartItems cartRemove={cartRemove} onAdd={onAdd} onRemove={onRemove} item={item} />
                </Grid>
              ))}
            </Grid>
            {cart.line_items.length !== 0 && (
              <div className={classes.cardDetails}>
                <Typography variant="h4">Subtotal: ${totalPrice.toFixed(2)}</Typography>
                <div>
                  <Button className={classes.emptyButton} size="large" type="button" variant="contained" onClick={() => cartEmpty()} color="secondary">Empty cart</Button>
                  <Button className={classes.checkoutButton} component={Link} to="/checkout" size="large" type="button" variant="contained" color="primary">Checkout</Button>
                </div>
              </div>
            )}
          </>
        </Container>
      );
}

export default Cart

修改完成后,购物车数据将完全匹配Commerce.js格式,可直接用于后续的订单提交等操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 14:40:50