简体   繁体   中英

react shoping cart mutation issue

I'm practicing React, developing a Store, for adding the feature of the Shopping Cart I use this example.

But in my implementation, even though my version is almost the same, the " add to cart " button doesn't differentiate between each product, meaning:

  • 1st click affect all the buttons not only the clicked one and the other buttons change to "add more" legend
  • each posterior click only adds more products of the same kind the user 1st clicked, ignoring if clicked another one.

Seems the error its caused by a mutation in a Reducer Function:

export const CartReducer = (state, action) => {
switch (action.type) {
    case 'ADD_ITEM':
      if (!state.cartItems.find((item) => item.id === action.payload.id)) {
        //-------HERE
        state.cartItems.push({
          //mutation here?
          ...action.payload,
          quantity: 1,
        });
        //-------
  }

  return {
    ...state,
    ...sumItems(state.cartItems),
    cartItems: [...state.cartItems],
  };

What would be an alternative to this? How do I push items in the state without a mutation?

The complete te file its here

Here you can check the deploy and replicate the error, and here its the correct functionality demo

You are mutating the original state , which is bad practice in redux. What you can do is something like this to prevent it:

export const CartReducer = (state, action) => {
    switch (action.type) {
        case 'ADD_ITEM':
            if (!state.cartItems.find((item) => item.id === action.payload.id)) {
                // If you have Lint problems with this declaration, you can set a variable before the switch
                const cartItems = [...state.cartItems, action.payload];

                return {
                    ...state,
                    ...sumItems(cartItems),
                    cartItems,
                };
            }

            return state;
    }
}

state.cartItems.push is wrong here, you are mutating the state (antipattern).

first you check whether your item exists as you did at the begging. If the item exists simply return the state. If not you can return you may return your state as

return {
                    ...state,
                    ...sumItems(state.cartItems + 1),
                    cartItems: [...state.cartItems, action.payload],
                };

Before going into details and complex update operations, you should be familiar with the topics array destruct, object destruct, shallow copy, spread operations, copying arrays, slice, splice, filtering operations. Otherwise you may perform some direct mutation as above.If they are too complex, you can use other libraries which make this operations easier, for example immutable.js But remember, using extra library will cause a small performance loss.

https://redux.js.org/recipes/using-immutablejs-with-redux

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM