Reputation: 197
I am trying to add things to a list, in the form of a state array. However, with my current code, the first item doesn't add itself properly.
export default class Main extends React.Component {
constructor(props) {
super(props);
this.state = {
list: [],
total: 0.00,
...
}
}
//some unimportant code here
addToList = item => {
this.setState({list: [...this.state.list, item]});
//This method call for a method that gets the total price of all the items
this.getTotal();
}
//this method works fine, except with the first element
getTotal() {
this.setState(({sum= 0.0, items, list}) => {
items.forEach(element => {
if(this.state.list.length !== 0.0) {
if(this.state.list.includes(element.name)) {
sum += parseFloat(element.price);
}
}
});
this.setState({total: sum});
});
}
}
When I console.log
the list
state I get an empty array for the first item, and then the items are delayed by one. So if I add the item A
and look at the console, I see nothing. When I add item B
and look at the console, I see an Array
with the item A
. Any ideas as to what is causing this?
Upvotes: 1
Views: 58
Reputation: 817128
Every access to this.state.list
should be replaced with list
. this.state.list
accesses potentially old state. The whole point of passing a callback is that you can access the current state passed as argument. You are doing this correctly for items
, but not for list
.
You should also return {total: sum}
from the setState
callback instead of calling this.setState
:
getTotal() {
this.setState(({items, list}) => {
const sum = 0;
items.forEach(element => {
if(list.includes(element.name)) {
sum += parseFloat(element.price);
}
});
return {total: sum};
});
}
For the same reason you should use a callback function in addToList
:
addToList = item => {
this.setState(({list}) => ({list: [...list, item]}));
this.getTotal();
}
Upvotes: 2
Reputation: 1879
Remember that setState is asyncronous, so if you wanna check the list updated, you have add a callback to the setState :
addToList = item => {
this.setState( {list: [...this.state.list, item]}, () =>{
// So if you make anything here, you are sure that the state was updated successfully
console.log( this.state.list );
this.getTotal();
} );
}
Upvotes: 1