>我正在创建一个带有反应钩子的购物车,如下所示
const ShoppingCart = () => {
const [products, setProducts] = useState([
{id: 1, name: 'Product 1', price: 2500},
{id: 2, name: 'Product 2', price: 2000},
{id: 3, name: 'Product 3', price: 2500},
])
const [cart, setCart] = useState()
const addToCart = (item) => (
setCart([cart, {item}])
// setCart([...cart, {item}])
// setCart([{item}])
)
return (
{
products.map((product, i) => (
<>
<Product name={product.name} price={product.price} key={product.id} />
<button
value='Add to cart'
// onClick={((product) => setCart(...cart, product))}
onClick={(product) => addToCart(product)}
// onClick={console.log(i)}
/>
{console.log(cart)}
</>
))
}
)
}
注释掉的行是我尝试过的一些不起作用的东西。在map中的lamda函数中没有第二个arg[i]的情况下也尝试了它。
我正在尝试在用户单击按钮后将产品添加到购物车对象
购物车的预期状态,例如,如果用户单击ID为1的产品旁边的按钮,则购物车的预期状态将是
[{id: 1, name:'Product 1', price: 2500}]
如果可能的话,我还想在对象中添加另一个字段,这将是金额
设置购物车的初始值
const [cart, setCart] = useState([]); // [] is the initial value of the cart
从传递给onClick
的回调中删除product
,因为它不是产品,而是click event
<button value="Add to cart" onClick={() => addToCart(product)} />
并且点差运算符应该工作正常
const addToCart = item => {
setCart([...cart, item]);
};
编辑
如果您只想添加一次商品,请先检查它是否存在于购物车中:
const addToCart = item => {
const ndx = cart.findIndex(e => e.id === item.id);
if (ndx === -1) {
setCart([...cart, item]);
}
};
请使用...cart 在您的 addToCart 函数中,因为 cart 将是以前的数据数组,当您这样做时 [...购物车,项目],然后以前的数组将合并到新数组中,并将在该新数组中添加新的产品对象。
const addToCart = (item) => (
setCart([...cart,item])
)
请不要将参数传递给您的点击回调函数,因为您是从上面而不是从点击函数获得此产品.使用这样的匿名函数
onClick={() => addToCart(product)}
使用onClick={((product) => setCart([...cart, product]))}