skip to Main Content

I’m storing an array of products added to a cart in a useState, each cart product has a quantity that can increase and decrease which all works fine.

I then wanted to display the total number of all the product quantities in the basket. Basically (Product 1 has a quantity of 2) + (Product 1 has a quantity of 3) = Total quantity of 5.

I thought I had the answer with the below code:

const [cartQuantity, setCartQuantity] = useState(0)

const updateCartTotals = () => {
  let TotalQuantity = 1;
  cartProducts.map(({productQuantity}) => TotalQuantity = TotalQuantity + productQuantity)
  setCartQuantity(TotalQuantity)
}

and when I run this function after each add to cart function I created has ran it does actually update the carts total quantity of products to the correct number matching the number of products added to the cart:

3 products

It also updates fine if I increase the number of quantity per item:

6 products

However if I reduce a quantity it still increases by 1 (should be 5 total but showing 7)

5 products

then if I reduce another one the total quantity does reduce but it’s now one behind where it should be at that point, and I’m not sure why.

I know I’m building something I haven’t before and working with React that I’m just getting used too, but I keep feeling rather silly because I get close to an answer to a problem but then I keep finding there’s an issue I can’t get my head around. So any help would be much appreciated.

Thanks

2

Answers


  1. This should not be a separate state, since you can calculate it directly from the other states. That will make it impossible for them to get out of sync.

    //const [cartQuantity, setCartQuantity] = useState(0)
    let cartQuantity = 0;
    cartProducts.forEach(({ productQuantity }) => cartQuantity = cartQuantity + productQuantity);
    

    If you’re concerned that this calculation is expensive (i for one am not concerned), you can wrap it in a useMemo so that it will only be recomputed when cartProducts change.

    const cartQuantity = useMemo(() => {
      let sum = 0;
      cartProducts.forEach(({ productQuantity }) => sum = sum + productQuantity);
      return sum;
    }, [cartProducts])
    
    Login or Signup to reply.
  2. I would rather do something like this:

    const updateCartTotals = () => {
      const totalQuantity = cartProducts.reduce((totalQuantity, {productQuantity}) => 
        totalQuantity + productQuantity), 0)
      return totalQuantity
    }
    

    So you are adding all the productQuantity and you store the final result inside totalQuantity
    And you can use the totalQuantity returned by this function wherever you need in your code. You don’t need to store it in a state

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search