Even though you've shallow copied the cart items array you are still mutating the individual items with the post increment.
const increaseHandler = (x) => {
let newCart = [...props.cartItems];
let exist = newCart.find((item) => item.id === x.id);
if (exist) {
exist.quantity++; // <-- mutation!!
} else {
exist = {
...props.cartItems,
quantity: 1,
};
}
newCart.push(exist); // <-- adds duplicate items
props.setCartItems(newCart);
};
You still need to create a new item reference, shallow copying the properties and updating the quantity property. You should only push new elements into the cart array.
const increaseHandler = (x) => {
const newCart = [...props.cartItems];
let exist = newCart.find((item) => item.id === x.id);
if (exist) {
exist = {
...exist,
quantity: exist.quantity + 1;
};
} else {
exist = {
...props.cartItems,
quantity: 1,
};
newCart.push(exist);
}
props.setCartItems(newCart);
};
It's more common to map the previous state to the next state, and I suggest using a functional state update to ensure correctly updating from the previous state versus any state closed over in callback scope (possibly stale).
const increaseHandler = (x) => {
props.setCartItems(items => {
const inCart = items.some((item) => item.id === x.id);
if (inCart) {
return items.map((item) => item.id === x.id
? {
...item,
quantity: item.quantity + 1,
}
: item);
}
return items.concat({
...props.cartItems,
quantity: 1,
});
});
};
newCart.push(exist)should be inside the else block.