我正在尝试制作一个简单的电子商务应用程序。当用户进入购物车部分并尝试增加或减少数量时,它会改变状态,但在页面上保持不变。我需要回去,去推车再次更新。它是如何动态变化的?
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>
))
})}
Issue
- 你的代码片段没有调用
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>
))
});
}
我建议使用带有上下文的reducer来管理状态。像下面的一个新的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 });
};
如果有帮助,你可以参考这个项目shopping-cart-with-context-api