如何在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
相关产品推荐
相关产品推荐

