反应如何处理添加到购物车



所以我有一个电子商务网页,但由于某种原因,在将第一次添加到购物车后,它开始使购物车中的单位价值翻倍,也使我的Toast翻倍。我想知道我在这里做错了什么。cartItem的初始状态为0。任何帮助都将不胜感激。

这是我正在使用的:

cartItem对象示例:

[{
description: "...."
featured: false
id: "6u7pLcaGApuGtiNAf6zLMf"
image: ["//images.ctfassets.net/f1r553pes4gs/17rq7BQ76Q7ouq…010636019e9b3cbc3a10/il_794xN.2378509691_kaep.jpg"]
inCart: false
ingredients: (2) ["Distilled Water", "99.99% Fine Silver Rods"]
price: 20
productName: "Quintessence Colloidal Silver (4 fl oz)"
slug: "quintessence-colloidal-silver-4oz"
units: 9
}]

代码的简短版本:

export class StoreProvider extends Component {
//Initialized State ready for API Data
state = {
products: [],
featuredProducts: [],
sortedProducts: [],
price: 0,
maxPrice: 0,
minPrice: 0,
units: 0,
loading: true,
//FIXME CART
cartItem: []
}
handleAddToCart = (e, products) => {
this.setState(state => {
const cartItem = state.cartItem;
let productsAlreadyInCart = false;
cartItem.forEach(cp => {
if (cp.id === products.id) {
//Have tried ++
cp.units+= 1;
productsAlreadyInCart = true;
this.successfullCartToast()
}
});
if (!productsAlreadyInCart) {
cartItem.push({ ...products});
}
localStorage.setItem('cartItem', JSON.stringify(cartItem));
return { cartItem: cartItem };
});
}
}
//Button is in seperate component
<button
className="btn-primary rounded col-sm-6 col-lg-12 align-self-center ml-1 p-2"
onClick={(e) => handleAddToCart(e, product)}>
+ Cart
</button>

问题

您正在更改现有状态烘烤您检查的每个购物车项目。

解决方案

如果项目已经包含,首先搜索购物车数组。如果它已经包含,那么只需映射购物车并更新适当的索引,否则,附加到浅复制的购物车项目数组中。

此外,setState应该是一个纯函数,所以不要在setState函数更新中设置localStorage之类的副作用,而是使用setState回调,或者最好使用componentDidUpdate生命周期函数。或者,您可以将localStorage设置为与更新状态相同的值。

handleAddToCart = (e, products) => {
const itemFoundIndex = this.state.cartItem.findIndex(
cp => cp.id === products.id
);
let cartItem;
if (itemFoundIndex !== -1) {
this.successfullCartToast();
// map cart item array and update item at found index
cartItem = this.state.cartItem.map((item, i) =>
i === itemFoundIndex ? { ...item, units: item.units + 1 } : item
);
} else {
// shallow copy into new array, append new item
cartItem = [...this.state.cartItem, products];
}
localStorage.setItem("cartItem", JSON.stringify(cartItem));
this.setState({ cartItem });
};

所以,cartItem是一个Object,看起来像:

[{'id': 123, 'units': 2}, {'id': 345, 'units': 1}, ...]

要尝试的一件事是对Object进行深度复制,这样它在更新时就不会更改:

handleAddToCart = (e, products) => {
this.setState(state => {
//const cartItem = state.cartItem;
// make deep copy, so state doesn't change while manipulating:
const cartItem = JSON.parse(JSON.stringify( state.cartItem ));
let productsAlreadyInCart = false;
cartItem.forEach(cp => {
if (cp.id === products.id) {
//Have tried ++
cp.units += 1;
productsAlreadyInCart = true;
this.successfullCartToast()
}
});
if (!productsAlreadyInCart) {
cartItem.push({ ...products});
}
localStorage.setItem('cartItem', JSON.stringify(cartItem));
return { cartItem: cartItem };
});
}
}

最新更新