useEffect does not see the state update

I’m trying to make the functionality of adding products to the cart with updating the counter of the number of products and the total amount.

I can’t understand why useEffect is triggered only when a new product is added to the cart. If I update the current quantity of the product that is already in the cart, then useEffect does not work.

  const [cart, setCart] = useState([])
  const [counter, setCounter] = useState(cart.reduce((prev, curr) => prev + curr.quantity, 0))
  const [total, setTotal] = useState(cart.reduce((prev, curr) => prev + curr.price, 0))

  const addItemToCart = (id, foodName, url, price, quantity) => {
    if (cart.find(el => el.id === id)) {
      cart.map(el => {
        if (id === el.id) {
          const price = el.price / el.quantity
          el.quantity += 1
          el.price = price * el.quantity
        }
        return setCart(cart) // useEffect does not work
      })
    } else {
      setCart(() => [...cart, { id, foodName, url, price, quantity }]) // useEffect is triggered
    }
  }

  useEffect(() => {
    setCounter(cart.reduce((prev, curr) => prev + curr.quantity, 0))
    setTotal(cart.reduce((prev, curr) => prev + curr.price, 0))
  }, [cart])

>Solution :

instead of this

 return setCart(cart) // useEffect does not work

write

      setCart(prevCart => prevCart.map(el => {
        if (id === el.id) {
          const price = el.price / el.quantity
          el.quantity += 1
          el.price = price * el.quantity
        }
        return el
      }))

Two issues with your code:

  cart.map(el => {
    if (id === el.id) {
      const price = el.price / el.quantity
      el.quantity += 1
      el.price = price * el.quantity
    }

This doesn’t return anything. Cart.map doesn’t mutate the list. So cart would just be the same I guess the objects would be mutated though, so setCart([...cart]) would work after that.

And

return setCart(cart) // useEffect does not work

setCart can only take a copy of cart. This also wont do anything (see: https://reactjs.org/docs/hooks-state.html)

Fully updated code

  const addItemToCart = (id, foodName, url, price, quantity) => {
    if (cart.find(el => el.id === id)) {
      setCart(prevCart => prevCart.map(el => {
        if (id === el.id) {
          const price = el.price / el.quantity
          el.quantity += 1
          el.price = price * el.quantity
        }
        return el
      }))

    } else {
      setCart(() => [...cart, { id, foodName, url, price, quantity }]) // useEffect is triggered
    }
  }

Leave a Reply