简体   繁体   中英

How to update item quantity in the shopping cart using React Redux

How to make my cart work better when I add a new item from the same product user can increase the quantity of the product instead of adding it to the cart.

Here is the code I have for my reducer:

import {ADD_TO_CART, REMOVE_FROM_CART, CLEAR_CART} from '../constants';

const initialState = {
  cartItems: [],
  totalPrice: 0,
};

const cartItems = (state = initialState, action: any) => {
  switch (action.type) {
    case ADD_TO_CART:
      return {
        ...state,
        cartItems: [...state.cartItems, action.payload],
        totalPrice: state.totalPrice + action.payload.price,
      };
    case REMOVE_FROM_CART:
      return {
        ...state,
        cartItems: state.cartItems.filter(
          cartItem => cartItem !== action.payload,
        ),
        totalPrice: state.totalPrice - action.payload.price,
      };
    case CLEAR_CART:
      return {...initialState};
  }
  return state;
};

export default cartItems;

I tried to do like so but it failed

import {ADD_TO_CART, REMOVE_FROM_CART, CLEAR_CART} from '../constants';

const initialState = {
  cartItems: [],
  totalPrice: 0,
};

const cartItems = (state = initialState, action: any) => {
  switch (action.type) {
    case ADD_TO_CART:
      const theItem = state.cartItems.find(
        product => product.name === action.payload.name,
      );

      if (theItem) {
        return {
          ...state,
          cartItems: [...state.cartItems, action.payload],
          totalPrice: state.totalPrice + action.payload.price,
          qty: theItem.qty + 1,
        };
      }

      return {
        ...state,
        cartItems: [...state.cartItems, action.payload],
        totalPrice: state.totalPrice + action.payload.price,
      };
    case REMOVE_FROM_CART:
      return {
        ...state,
        cartItems: state.cartItems.filter(
          cartItem => cartItem !== action.payload,
        ),
        totalPrice: state.totalPrice - action.payload.price,
      };
    case CLEAR_CART:
      return {...initialState};
  }
  return state;
};

export default cartItems;

I think there is no need to share action because the Cart works 100% well , But I will share it,

import {ADD_TO_CART, REMOVE_FROM_CART, CLEAR_CART} from '../constants';

export const addToCart = (payload: any) => {
  return {
    type: ADD_TO_CART,
    payload,
  };
};

export const removeFromCart = (payload: any) => {
  return {
    type: REMOVE_FROM_CART,
    payload,
  };
};

export const clearCart = () => {
  return {
    type: CLEAR_CART,
  };
};

and finally the screen with the payload

  const product = {
    id: 1,
    name: 'LAptop',
    price: 1000,
    qty: 0,
    // imgURL:
    //   'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_160x56dp.png',
  };

....

      <Button
        title="Add 1"
        onPress={() => {
          dispatch(addToCart(product));
          console.log(cartData);
        }}
      />

....

Firstly I would suggest starting at quantity 1 when adding an item to the cart.

const product = {
  id: 1,
  name: 'Laptop',
  price: 1000,
  qty: 1,
  imgURL: ...,
  ...
};

...

<Button
  title="Add 1"
  onPress={() => {
    dispatch(addToCart(product));
    console.log(cartData);
  }}
/>

In the reducer, you were on the right idea to first search through the cart array to see if the product was already in the cart. Where you went off-track was if the item is already in the cart then you want to increment the item quantity property, otherwise you add the entire item to the cart.

case ADD_TO_CART:
  const { payload } = aciton;
  const item = state.cartItems.find(
    product => product.id === payload.id,
  );

  if (item) {
    return {
      ...state,
      cartItems: state.cartItems.map(item => item.id === payload.id
        ? {
          ...item,
          qty: item.qty + 1,
        }
        : item
      ),
      totalPrice: state.totalPrice + payload.price,
    };
  }

  return {
    ...state,
    cartItems: [...state.cartItems, payload],
    totalPrice: state.totalPrice + payload.price,
  };

Similarly for REMOVE_FROM_CART you first check if the quantity will go to 0, if so then filter the item from the cart array, otherwise map the cart and decrement the quantity property. If you need to see an example I can update my answer to include it.

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