Reputation: 339
Hello guys I have an array like this :
[
{
"name": "test",
"amount": 794.651786,
"id": "60477897fd230655b337a1e6"
},
{
"name": "test2",
"amount": 10.80918,
"id": "60477bfbfd230655b337a1e9"
}
]
And i wan't to make the total of every amount.
I tried by using the useState hook like this :
const [total, setTotal] = useState(Number);
array.map((item) => {
setTotal(total + item.amount);
});
but it doesn't seems to work as expected.
Upvotes: 1
Views: 2108
Reputation: 55663
My comment wasn't addressed but I'm going to add an answer which addresses my concern - total
shouldn't be state at all.
total
most likely isn't state - it's computed state - i.e. it's derived from other state and/or props.
If that's the case (99% that it is) it's not correct to set total as state, that just makes for more code and more complicated debugging:
Examples:
When the source of data is a prop:
const Cart = ({someItemsInMyCart}) => {
const total = useMemo(() => someItemsInMyCart.reduce((acc,item) => acc+item.amount,0),[someItemsInMyCart]);
return (/* some JSX */);
}
When the source of data is state:
const Cart = () => {
const [items,setItems] = useState([]);
const total = useMemo(() => items.reduce((acc,item) => acc+item.amount,0),[items]);
return (/* some JSX */);
}
You can write those two examples above and completely leave out the useMemo
, which is just a perf optimization, because reducing an array in that manner is pretty darn fast unless you're dealing with 1000s of items.
Upvotes: 2
Reputation: 527
You would want to update the state with the minimum calls needed. so first, I would do it like this:
let _total = 0;
array.forEach((item) => {
_total += item.amount;
});
setTotal(_total);
That said, You would want to only execute this if array
has changed. Assuming array is a prop, this can be done easily with useEffect
hook:
useEffect(()=>{
let _total = 0;
array.forEach((item) => {
_total += item.amount;
});
setTotal(_total);
},[array]);
Hope this helps you get a full picture of what the best practice would be. Also you can check out the rules of hooks to get a better understanding on where is best to call setState
Upvotes: 3
Reputation: 5112
You could use the reduce method, see docs.
setTotal(array.reduce((sum, item) => sum + item.amount, 0))
I invite you to read this JavaScript: Difference between .forEach() and .map() as well. You should never use .map
like this. For this use case, use .forEach
instead.
Upvotes: 5
Reputation: 546
Try this way
const [total, setTotal] = useState(0);
array.map((item) => {
setTotal(prevCount => prevCount + item.amount);
});
Upvotes: 0