Javascript 反应如何处理添加到购物车
所以我有一个电子商务网页,但出于某种原因,在第一次向购物车添加物品后,它开始使购物车中的单位价值翻倍,并使我的祝酒词翻倍。我想知道我在这里做错了什么。cartItem的初始状态为0。任何帮助都将不胜感激 以下是我的工作内容: cartItem对象的示例:Javascript 反应如何处理添加到购物车,javascript,reactjs,e-commerce,shopping-cart,Javascript,Reactjs,E Commerce,Shopping Cart,所以我有一个电子商务网页,但出于某种原因,在第一次向购物车添加物品后,它开始使购物车中的单位价值翻倍,并使我的祝酒词翻倍。我想知道我在这里做错了什么。cartItem的初始状态为0。任何帮助都将不胜感激 以下是我的工作内容: cartItem对象的示例: [{ description: "...." featured: false id: "6u7pLcaGApuGtiNAf6zLMf" image: ["//images.ctfassets.n
[{
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>
导出类StoreProvider扩展组件{
//API数据的初始化状态就绪
状态={
产品:[],
特色产品:[],
分类产品:[],
价格:0,,
maxPrice:0,
价格:0,
单位:0,,
加载:对,
//修理车
项目:[]
}
HandleadToCart=(e,产品)=>{
this.setState(state=>{
const cartItem=state.cartItem;
让ProductsReadyInCart=false;
cartItem.forEach(cp=>{
if(cp.id==products.id){
//试过++
cp.units+=1;
ProductsReadyInCart=true;
这个。successfullCartToast()
}
});
如果(!ProductsReadyInCart){
推送({…产品});
}
setItem('cartItem',JSON.stringify(cartItem));
返回{cartItem:cartItem};
});
}
}
//按钮位于单独的组件中
手持式(e,产品)}>
+推车
因此,cartItem是一个对象,看起来像:
[{'id':123,'units':2},{'id':345,'units':1},…]
要尝试的一件事是创建对象的深度副本,以便在更新时不会更改:
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 };
});
}
}
问题
您正在改变现有状态,并对您检查的每个购物车项目进行烘烤
解决方案
如果项目已包含,则首先搜索购物车数组。如果它已经被包含,那么只需映射购物车并更新适当的索引,否则,附加到一个简单复制的购物车项目数组
另外,setState
应该是一个纯函数,所以不要在setState
函数更新中设置localStorage这样的副作用,而是使用setState
回调,或者最好使用componentdiddupdate
生命周期函数。或者,您可以使用更新状态时使用的相同值设置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 });
};
你能分享更多你的代码吗?可能是完整的组件,你可以在其中初始化你的状态。我可以添加更多,但都在一个上下文中,所以这个组件中有250多行