I have a problem when I dispatch an action that triggers my ADD_TO_CART type. I want to increase the quantity of a specific number added in the cart when user click on it. The numbers I'm getting for quantity are : 1, 3, 5, 7, 9.. But they should be incremented only by 1 like 1, 2, 3, 4, 5. Why am I getting double increments in my if statement when I wanna update state indirectly without mutating it? Any kind of help is highly appreciated.
Here is my code :
switch(action.type){
case 'ADD_TO_CART':
let tempCart = [...state.cart];
let specificIndex = state.cart.findIndex((obj) => obj.id === action.item.id);
if(specificIndex >= 0){
tempCart[specificIndex].quantity +=1; // it should increment only by 1 and not by 2
tempCart[specificIndex].price += action.item.price;
return{
...state,
cart : tempCart,
}
}
And here is my state for the example above:
export const initialState = {
cart: [],
};
I suspect this is because you are treating tempCart
as mutable (adding to its members directly), when really it is just a reference to (not a copy of) part of state
, which should always be treated as immutable. Instead, try something like the following:
switch (action.type) {
case "ADD_TO_CART":
let specificIndex = state.cart.findIndex(
(obj) => obj.id === action.item.id
);
if (specificIndex >= 0) {
return {
...state,
cart: state.cart.map((item, idx) =>
idx == specificIndex
? {
...item,
quantity: item.quantity + 1,
price: item.price + action.item.price,
}
: item
),
};
}
}
See Immutable Update Patterns for more. Note that, even in this small example, these sorts of updates can quickly become unwieldy. There are helper libraries available that can simplify the process, if you are so inclined.