我刚开始反应并为咖啡店制作一个简单的购物车。每当我将一个项目添加到购物车时,如果该项目尚未在购物车中,那么我基本上将其与其余项目一起添加,并将
quantity
属性设置为 1 ,每当我再次添加相同的项目时,我只取整个项目项目并通过执行quantity++
更新相应的项目数量。但我不知道为什么数量会自行更新两个。我已经尝试过调试它,但我无法理解为什么会发生这种情况,为什么它不更新 1,而是更新 2。
这是我的应用程序组件 -:
import CoffeeShop from "./CoffeeShop"
function App() {
return (
<>
<h1 style={{ textAlign: "center" }}>Coffee Shop</h1>
<CoffeeShop />
</>
)
}
export default App
这是我的 CoffeeShop 组件 -:
在此组件中,我正在处理添加到购物车行为
import "./CoffeeShop.css";
import CoffeeItems from "./CoffeeItems";
import ShoppingCart from "./ShoppingCart";
import { useState } from "react";
export default function CoffeeShop() {
const [cartItems, setCartItems] = useState([]);
const [totalPrice, setTotalPrice] = useState(0);
const addToCart = (id, item) => {
console.log(cartItems);
setCartItems(currItems => {
const idx = currItems.findIndex(cartItem => cartItem.id === id);
if (idx !== -1) {
const newItems = [...currItems];
newItems[idx].quantity++;
return newItems;
}
return [...currItems, { ...item, quantity: 1 }];
});
setTotalPrice(currTotalPrice => currTotalPrice + item.price);
};
return (
<div className="CoffeeShop">
<CoffeeItems addToCart={addToCart} />
<ShoppingCart cartItems={cartItems} totalPrice={totalPrice} />
</div>
);
}
这是我的 CoffeeItems 组件 -:
import { useEffect } from "react";
import { useState } from "react";
import fetchProducts from "./productsApi";
import CoffeeItem from "./CoffeeItem";
import "./CoffeeItems.css";
import { v4 as uid } from "uuid";
export default function CoffeeItems({ addToCart }) {
const [products, setProducts] = useState([]);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
const fetchData = async () => {
setIsLoading(true);
const data = await fetchProducts();
setIsLoading(false);
for (let product of data) {
product.id = uid();
}
setProducts(data);
}
fetchData();
}, []);
return (
<div className="CoffeeItems">
{isLoading && <h1>Loading...</h1>}
{products.map(product => <CoffeeItem product={product} addToCart={addToCart} key={product.id} />)}
</div>
);
}
**CoffeeItems 组件基本上获取模拟数据,其中每个产品如下:**
{
"id": 3,
"name": "Tea set",
"price": 39.99,
"description": "This tea set is a complete tea-making solution for tea enthusiasts. It consists of a beautiful and functional kettle for boiling water and a set of delicate tea cups designed for serving tea. The kettle is made of ceramic and comes with a handle and spout for easy pouring. The tea cups are small and dainty with a simple yet elegant design. Whether for a quiet afternoon tea with a friend, a family gathering, or a special event, this tea set offers a classic and sophisticated way to enjoy a relaxing cup of tea.",
"image": "alisher-sharip-mumpl9-D7Uc-unsplash.jpg"
}
这是我的 CoffeeItem 组件 -:
import "./CoffeeItem.css";
export default function CoffeeItem({ product, addToCart }) {
const handleAddToCart = (e) => {
e.preventDefault();
addToCart(product.id, product);
}
return (
<div className="CoffeeItem">
<h2>{product.name}- ${product.price}</h2>
<img src={product.image} alt="product image" />
<div>
<button onClick={handleAddToCart}>Add to cart</button>
</div>
</div>
);
}
这是我的 ShoppingCart 组件 -:
import "./ShoppingCart.css";
import CartItem from "./CartItem";
export default function ShoppingCart({ cartItems, totalPrice }) {
return (
<div className="ShoppingCart">
<h1>Shopping Cart</h1>
{cartItems.length === 0 && <h2>Your cart is empty</h2>}
{cartItems.length > 0 && <h2>total: ${totalPrice}</h2>}
{cartItems.map(cartItem => <CartItem cartItem={cartItem} key={cartItem.id} />)}
</div>
);
}
**这是我的 CartItem 组件 -: **
import "./CartItem.css";
export default function CartItem({ cartItem }) {
return (
<div className="CartItem">
<h2>Name: {cartItem.name}</h2>
<h3>Price: ${cartItem.price}</h3>
<h3>Quantity: {cartItem.quantity}</h3>
</div>
);
}
在 CoffeeShop 组件中,当对购物车中已有的某个商品执行 addCart 处理程序时,它会在代码中添加
+1
。但它实际上将 +2
添加到相应产品的数量属性中。我不知道为什么会发生这种情况。请帮忙。
编辑
我刚刚从 main.jsx 文件中删除,现在一切正常。但为什么?
这是main.jsx文件
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.jsx'
import './index.css'
createRoot(document.getElementById('root')).render(
<StrictMode>
<App />
</StrictMode>,
)
**当我删除一切工作正常。但为什么 ? **
这很微妙,但你正在改变状态:
newItems[idx].quantity++;
在 React 中始终要避免这种情况,并且可能会导致像您所看到的那样的错误。 (具体来说,您看到的也是
StrictMode
渲染组件两次的结果。)
从根本上来说,永远不要改变 React 中的状态。 制作数组的浅拷贝是不够的:
const newItems = [...currItems];
因为两个数组仍然引用相同的对象。 因此,编辑一个数组中的对象会同时在两个数组中编辑该对象。 您可以将数组“投影”到一个新数组中,并在该投影中找到值时替换该值。 例如,考虑这个:
setCartItems(currItems =>
const idx = currItems.findIndex(cartItem => cartItem.id === id);
if (idx !== -1) {
return currItems.map((item, i) =>
i === idx ?
{ ...item, quantity: item.quantity + 1 } :
item
);
}
return [...currItems, { ...item, quantity: 1 }];
});
这里的想法是,当
map
迭代
currItems
时,它专门寻找您要定位的索引。 对于该索引处的项目,它返回一个全新的项目,其中包含与现有项目相同的属性,但具有新的 quantity
值。 对于数组的每个其他索引,它只按原样返回现有项目。