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:
It also updates fine if I increase the number of quantity per item:
However if I reduce a quantity it still increases by 1 (should be 5 total but showing 7)
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
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])