Home > Mobile >  Update object inside array in useState
Update object inside array in useState

Time:10-14

I have this cart state in which the initial value is an empty array [].

const [cart,setCart] = useState([]);

This is how one of my product object looks like,

{id: 1, name: 'Shoe pair', price: 40}

There is an add to cart button for each product. So when the add to cart button is clicked addToCart function is triggered,

const addToCart = (item) => {
  let initialItem = {id: item.id, name: item.name, quantity: 1} 
  let existingItem = cart.filter(cartItem => item.id === cartItem.id);
  if(existingItem.length > 0){
    existingItem.quantity = existingItem.quantity   1;
  } else {
    setCart(crr => [...crr, initialItem ]);
  }
}

What does addToCart do? As you can see it is simple.First, it creates an object by setting the initial quantity to 1. If already the same product is present in the cart it updates the quantity in the cart product by 1 else the initialItem being added to the cart.

To monitor this occurrence I used useEffect hook,

useEffect(() => {
 console.log(cart);
}, [cart]);

My problem is I can't see the cart in the console log when the quantity updates by 1 , But it shows when the initialItem is being pushed to the cart.

CodePudding user response:

First issue: It is find, not filter.

Next issue - modifying item inside of array will not tell React that array is changed, you need to re-set state after existing item update also.

const addToCart = (item) => {
  const initialItem = { id: item.id, name: item.name, quantity: 1 };
  const existingItem = cart.find((cartItem) => item.id === cartItem.id);
  if (existingItem) {
    existingItem.quantity  = 1;
    setCart((curr) => [...curr]);
  } else {
    setCart((curr) => [...curr, initialItem]);
  }
};

CodePudding user response:

The reason your useEffect is not running when you think it should, is because its dependency is not being updated when you think it is. It will run when setCart is called and the reference to cart is updated, and then you will see your console log.

filter returns a new array -- will not mutate the original array. docs -> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

find returns the item by reference, if found -- otherwise returns undeifined. docs -> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find

Alternate example:

const addToCart = (item) => {
  let updatedCart = return cart.reduce((cart, cartItem) => {
      if (cartItem.id === item.id) {
        return [...cart, { ...item, quantity: item.quantity   1 }]
      } else {
        return [...cart, item]
      }
    }, [])

  setCart(updatedCart)
}
  • Related