1

first of all I have to mention that i'm a bit new to react but I've spent couple of hours on a problem with useReducer and couldn't understand it . here is my code:

const defaultCartState = {
items: [],
totalAmount: 0,
};
//action = {type:"ADD" , item:item}
const cartReducer = (state, action) => {
if (action.type === "ADD") {
    const updatedTotalAmount = parseFloat(
    state.totalAmount + action.item.price * action.item.amount
    ).toFixed(2);

    const existingCartItemIndex = state.items.findIndex(
    (item) => item.id === action.item.id
    );
    const existingCartItem = state.items[existingCartItemIndex];

    let updatedItems;
    if (existingCartItem) {
        const updatedItem = state.items[existingCartItemIndex];
        updatedItem.amount =
        state.items[existingCartItemIndex].amount + action.item.amount;
        const updatedItems = [...state.items];
        updatedItems[existingCartItemIndex] = updatedItem;
        return {
          items: updatedItems,
          totalAmount: updatedTotalAmount,
        };
        } else {
             const updatedItems = state.items.concat(action.item);
        return {
             items: updatedItems,
             totalAmount: updatedTotalAmount,
        };
     }
}
return defaultCartState;
};

its simply my reducer function state include an array named items which each element of this array is an object with a amount value. and here is my useReducer initialization:

 const [cartState, dispatchCartAction] = useReducer(cartReducer,defaultCartState);

my problem is with these two lines of code :

if (existingCartItem) {
   const updatedItem = state.items[existingCartItemIndex];
   updatedItem.amount =
   state.items[existingCartItemIndex].amount + action.item.amount;

if I swap these two lines of code with these everything works fine .

if (existingCartItem) {
  const updatedItem = {
    ...existingCartItem,
    amount: existingCartItem.amount + action.item.amount,
  };

I want to know what is the problem ? why my approach doesn't work? what is the difference between defining an item like my solution and the real solution ? thank you in advance

zhulien
  • 5,145
  • 3
  • 22
  • 36
amir_70
  • 737
  • 1
  • 10
  • 27

1 Answers1

3

As reducers are pure functions you cannot mutate state directly. That is why the second method is working. You need to copy the previous state and then and create a new object every time.

I think this may help more (if I understood the question correctly);

possum
  • 1,837
  • 3
  • 9
  • 18
Irfan wani
  • 4,084
  • 2
  • 19
  • 34
  • but my problem is that in the first approach also I haven't mutate the actual state . I just defined a new const updatedItem but didn't mutate my state at all. am I wrong ? – amir_70 Nov 27 '21 at 11:59