【发布时间】:2021-12-27 23:55:53
【问题描述】:
我正在尝试通过使用上下文来实现购物车。上下文工作正常,但我需要创建一种每次点击删除一个产品的方法。为此,我必须使用 useState() 函数。但是,它甚至不会改变状态中的数据。
这是我的函数代码。如果有什么不清楚的地方请告诉我
了解更多信息。 productsToPurchase 是一个包含所有已购买产品的数组,如下所示:
[{itemId: "ps-5", qty:2},{itemId: "iphone-xr", qty:4},{itemId:"ps-4", qty:7}]
export const CartContext = createContext()
class CartContextProvider extends Component {
state = {
productsToPurchase: [],
totalPrice:[]
}
addProduct = (itemId, prices) => {
this.setState(oldState => {
const objWithIdExist = oldState.productsToPurchase.find((o) => o.itemId === itemId);
return {
productsToPurchase: !objWithIdExist
? [...oldState.productsToPurchase, { itemId, qty: 1, price: prices }]
: oldState.productsToPurchase.map((o) =>
o.itemId !== itemId ? o : { ...o, qty: o.qty + 1 }
)
}
})
this.setState(oldState=>{
return{
totalPrice: getTotalAmount(oldState.productsToPurchase)
}
})
}
decreaseProduct = (itemId) =>{
this.setState(oldState=>{
// catch the item by mapping
return oldState.productsToPurchase.map(product=>{
if (product.itemId === itemId){
if (product.qty === 1){
//remove the product from the list
console.log("qty is 1!")
}
else {
console.log("Quantity is more than 1")
return {...product, qty: product.qty - 1}
}
}
})
})
}
render() {
return (
<CartContext.Provider value={{...this.state, addProduct: this.addProduct, decreaseProduct: this.decreaseProduct}}>
{this.props.children}
</CartContext.Provider>
)
}
}
function getTotalAmount(productsToPurchase) {
const totalPrice = []
productsToPurchase.map((product, productIndex) =>{
product.price.map((price, priceIndex)=>{
if (productIndex === 0){
totalPrice.push({currency: price.currency, amount: price.amount * product.qty})
}
else {
totalPrice.map(total=>{
if (total.currency === price.currency){
total.amount = total.amount + (price.amount * product.qty)
}
})
}
})
})
return totalPrice
}
export default CartContextProvider;
【问题讨论】:
-
您需要在
setState()回调中返回新状态。见reactjs.org/docs/hooks-reference.html#functional-updates -
您的回调 (
oldState => { ... }) 没有返回任何内容,因此永远不会写入新状态 -
这是
map回调中的返回,而不是setState回调。您似乎还使用map代替for..of或forEach,这不是它的用途(为什么开发人员继续这样做?) -
@asemshaat 您没有返回新状态。应该是
return oldState.productsToPurchase.map(...。您传递给setState的函数需要返回新状态。您正在谈论的返回是嵌套在 inside 的 map 函数。此外,如果您想从列表中删除产品,您也需要使用.filter,或者.reduce可用于在一次迭代中进行映射和过滤 -
提供者是一个类组件,而其他一切都是钩子和功能组件,这似乎很奇怪。我会让一切都发挥作用。
标签: javascript reactjs react-context