React Redux update item quantity (more than just one increment)

Viewed 1854

I have a site where the user can increase the quantity on the product before adding it to cart. Now if the user decided to go back to the product and add 3 more by increasing the quantity on the product, then adding to cart - how do I update the quantity of the existing product in basket?

At the moment I get duplicates of the product with different quantities depending on what is selected.

Here is the code I have for my reducer:

import { createSlice } from "@reduxjs/toolkit";

const initialState = {
  items: [],
};

const basket = createSlice({
  name: "basket",
  initialState,
  reducers: {
    addToBasket: (state, { payload }) => {
        // No idea what to do with this..
      state.items.filter((pizza) => pizza.name === payload.name);

      // This pushes the item fine, but I get multiple of the same item in the cart instead of just updating its quantity
      state.items.push(payload);



      //   state.items.map((pizza) =>
      //     pizza.name === payload.name
      //       ? {
      //           ...pizza,
      //           quantity: pizza.quantity + payload.quantity,
      //         }
      //       : pizza
      //   );


    },
  },
});

export const { addToBasket } = basket.actions;
export const basketItems = (state) => state.basket.items;

export default basket.reducer;

The payload is the specific product, it will be an object:

{
 name: "product name",
 image: "url.jpeg",
 price: "14.99"
}

I can not for the life of me figure out what to do here in order not to mutate the state. Nothing works, I feel like I have tried every possible way but clearly I am missing something.

Any help much appreciated!!!

Thanks

1 Answers

You actually have all the code you need, just need it applied correctly. First check that the item is already in the items array or not. If it is already there then copy the existing state and update the matching element. If it is not included then append the new item to the end of the array.

const basket = createSlice({
  name: "basket",
  initialState,
  reducers: {
    addToBasket: (state, { payload }) => {
      const item = state.items.find((pizza) => pizza.name === payload.name);

      if (item) {
        state = state.items.map((pizza) =>
          pizza.name === payload.name
            ? {
                ...pizza,
                quantity: pizza.quantity + payload.quantity
              }
            : pizza
        );
      } else {
        state.items.push(payload);
      }
    },
  },
});

With Redux-Toolkit you can mutate the state objects so you can likely simplify this a bit. Instead of mapping a new array and setting it back to state, jut mutate the found object.

const basket = createSlice({
  name: "basket",
  initialState,
  reducers: {
    addToBasket: (state, { payload }) => {
      const item = state.items.find((pizza) => pizza.name === payload.name);

      if (item) {
        item.quantity += payload.quantity;
      } else {
        state.items.push(payload);
      }
    },
  },
});
Related