Reputation: 81
I'm making a shopping cart app and I have a variable that loops through all prices and gets a total price of the cart. I am trying to have that total amount update the totals state through setTotals but while the total variable itself updates as items are removed from the cart, calling setTotals(total) does not update the state. It stays with the initial state on render (total price of all prices in cart).
my state declaration:
const [totals, setTotals] = useState()
getting the total from prices array:
var total = 0
for (var i = 0; i < prices.length; i++) {
total += prices[i];
}
calling setTotals in useEffect:
useEffect(() => {
setTotals(total) <-- From the loop above
setCartCopy([...deepCartCopy])
}, [totals])
Can anyone please help?
Upvotes: 2
Views: 13764
Reputation: 116
I think your approach of a card code is not the good one.
Here you always have the same information twice: you're getting the total in total
and then you're setting totals
with that same result. You can simplify by keeping only one of the two variables.
Also your code here is not working because the useEffect will never be executed: As you have put totals
as a dependency, but it never changes. Even if you change totals
somwhere else, you will have an infinite loop because in the useEffect depending on totals
's changes, it change it value, which will execute the useEffect that changes totals
etc etc, infinite loop.
I think your loop should also be in a useEffect with no dependencies as it will be executed only at the first render.
I would do soemthing like that, and maybe the code can be move improved:
const [prices, setPrices] = useState([1, 3, 6, 39, 5]);
const [total, setTotal] = useState(0);
useEffect(() => {
// Sets total with already present products in the card
// This useEffect is called only at the first render
prices.forEach((price) => {
setTotal((total) => total + price);
});
}, []);
useEffect(() => {
setTotal((total) => total + prices[prices.length - 1]);
// Called when prices values changes, like if you're adding a product to your card
// It keeps your total updated
}, [prices]);
const addPrice = () => {
// Simulate a new product in your card
setPrices((prices) => [...prices, Math.floor(Math.random() * 10)]);
};
return (
<div className="App">
<p>total: {total}</p>
<button onClick={() => addPrice()}>add price</button>
</div>
);
I hope I'm clear in my answer lol
Upvotes: 4
Reputation: 409
const [finalTotal, setFinalTotal] = useState(0);
let total = 0;
for (let i = 0; i < prices.length; i++) {
total += prices[i];
}
useEffect(() => {
setFinalTotal(total);
}, [total, setFinalTotal]);
https://codesandbox.io/s/stackoverflowhelp-i70fd?file=/src/App.js
Upvotes: 0