我正在尝试制作一个简单的电子商务应用程序。当用户进入购物车部分并尝试增加或减少数量时,它会更改状态但在页面上保持不变。我需要回去再去购物车更新。它如何动态变化?
function CardItem() {
const {cart, setCart} = useContext(ProductContext)
const addQuantity = (cartItem) => {
return cart.map((item) => (
cartItem.id === item.id ? item.quantity = item.quantity + 1 : item
))
}
const removeQuantity = (cartItem) => {
cart.map((item) => (
cartItem.id === item.id ? item.quantity = item.quantity - 1 : item
))
}
return (
{
cart.map((cartItem) => (
<tr key={cartItem.id}>
<td class="quantity__item">
<div class="quantity">
<div class="pro-qty-2 d-flex align-items-center justify-content-center text-center">
<button className='increase' onClick={() => removeQuantity(cartItem)}>
-</button>
{cartItem.quantity}
<button className='increase' onClick={() => addQuantity(cartItem)}>+</button>
</div>
</div>
</td>
</tr>
))
})}
回答1
问题
- 您的代码段中的代码没有调用
setCart
来更新任何状态。 - 添加/删除数量处理程序只是改变
cart
状态对象。不要改变 React 状态。
解决方案
使用 setCart
状态更新函数将状态更新加入队列以触发重新渲染以查看更新后的状态。使用功能状态更新从先前的状态正确更新,并记住您应该浅拷贝任何正在更新的状态。
例子:
function CardItem() {
const { cart, setCart } = useContext(ProductContext);
const addQuantity = (cartItem) => {
setCart(cart => cart.map(item => cartItem.id === item.id
? { // <-- new item object reference
...item, // <-- shallow copy item
quantity: item.quantity + 1, // <-- update property
}
: item
));
};
const removeQuantity = (cartItem) => {
setCart(cart => cart.map(item => cartItem.id === item.id
? {
...item,
quantity: item.quantity - 1,
}
: item
));
};
return (
{cart.map((cartItem) => (
<tr key={cartItem.id}>
<td class="quantity__item">
<div class="quantity">
<div class=" .... ">
<button className='increase' onClick={() => removeQuantity(cartItem)}>
-
</button>
{cartItem.quantity}
<button className='increase' onClick={() => addQuantity(cartItem)}>
+
</button>
</div>
</div>
</td>
</tr>
))
});
}
由于添加/删除本质上是相同的操作,因此通常使用单个函数来处理两者并传递您想要调整的数量。
function CardItem() {
const { cart, setCart } = useContext(ProductContext);
const addQuantity = (id, amount) => () => {
setCart(cart => cart.map(item => cartItem.id === id
? {
...item,
quantity: item.quantity + amount,
}
: item
));
};
return (
{cart.map((cartItem) => (
<tr key={cartItem.id}>
<td class="quantity__item">
<div class="quantity">
<div class=" .... ">
<button
className='increase'
onClick={addQuantity(cartItem.id, -1)}
>
-
</button>
{cartItem.quantity}
<button
className='increase'
onClick={addQuantity(cartItem.id, 1)}
>
+
</button>
</div>
</div>
</td>
</tr>
))
});
}
回答2
我会推荐使用带有上下文的 reducer 来管理状态。类似于下面的带有 ADD 和 REMOVE 项目等操作的新 CartReducer
const [state, dispatch] = useReducer(CartReducer, initalState);
const addToCart = (id) => {
dispatch({ type: ADD, payload: id});
};
const showHideCart = () => {
dispatch({ type: SHOW, payload:'' });
};
const removeItem = (id) => {
dispatch({ type: REMOVE, payload: id });
};
如果对 https://github.com/TommmyKelly/shoping-cart-with-context-api/tree/1124f7f0ff06b40b2f7bd2c451ffd6ed10323b61 有帮助,你可以参考这个项目