React setState not updating state
Solution 1
setState()
is usually asynchronous, which means that at the time you console.log
the state, it's not updated yet. Try putting the log in the callback of the setState()
method. It is executed after the state change is complete:
this.setState({ dealersOverallTotal: total }, () => {
console.log(this.state.dealersOverallTotal, 'dealersOverallTotal1');
});
Solution 2
setState is asynchronous. You can use callback method to get updated state.
changeHandler(event) {
this.setState({ yourName: event.target.value }, () =>
console.log(this.state.yourName));
}
Solution 3
In case of hooks, you should use useEffect
hook.
const [fruit, setFruit] = useState('');
setFruit('Apple');
useEffect(() => {
console.log('Fruit', fruit);
}, [fruit])
Solution 4
Using async/await
async changeHandler(event) {
await this.setState({ yourName: event.target.value });
console.log(this.state.yourName);
}
Solution 5
The setState is asynchronous in react, so to see the updated state in console use the callback as shown below (Callback function will execute after the setState update)
this.setState({ email: '[email protected]' }, () => {
console.log(this.state.email)
)}
The worm
Updated on July 08, 2022Comments
-
The worm almost 2 years
So I have this:
let total = newDealersDeckTotal.reduce(function(a, b) { return a + b; }, 0); console.log(total, 'tittal'); //outputs correct total setTimeout(() => { this.setState({ dealersOverallTotal: total }); }, 10); console.log(this.state.dealersOverallTotal, 'dealersOverallTotal1'); //outputs incorrect total
newDealersDeckTotal
is just an array of numbers[1, 5, 9]
e.g. howeverthis.state.dealersOverallTotal
does not give the correct total buttotal
does? I even put in a timeout delay to see if this solved the problem. any obvious or should I post more code?-
Assan over 7 years
-
Felix Kling over 7 yearsBesides what is said in the answers, you are explicitly logging the value of the state, before you are calling
setState
. -
The worm over 7 years@FelixKling no I'm calling this.state after I set it. I am logging a variable before. no?
-
Fabian Schultz over 7 yearsBecause of the timeout your
setState
is indeed executed after you log the state. I think what you meant to do in debugging was putting theconsole.log
part inside the timeout, and thesetState
outside. -
The worm over 7 years@FabianSchultz can you explain one thing I'm not getting then. consider this code:
if(this.state.playersOverallTotal > 21){ console.log('bust'); this.setState({playerBusted: true}); }
when it gets to over 21, the log fires but the state does not change and then only changes once the number increments again. e.g. if it got to 24 it would not set the state but then if it got to 28 for example it would -
Fabian Schultz over 7 yearsCan't reproduce it, maybe ask as a seperate question.
-
ggorlen almost 3 yearsDoes this answer your question? setState doesn't update the state immediately
-
-
Felix Kling over 7 yearsIn addition to that, the OP explicitly logs the state value before they call
setState
. -
Jozcar almost 7 yearsThis works for me as well, in the past I have used this: `this.setState({someVar: newValue},function(){ console.log("force update}); ' but for some reason it was't worring any more, when I updated the code as describe above it work. any idea why?
-
Fabian Schultz almost 7 years@Jozcar Should work also, syntax wasn't right (missing parentheses):
this.setState({someVar: newValue},function(){ console.log("force update") });
-
Johncy over 5 yearsimgur.com/Ku0OjTl Please tell me what should i do to get rid of this problem.
-
Santosh Singh over 4 yearsJavaScript is always synchronous.
-
Shubham Khatri over 4 years@santoshsingh you have a misconception. API calls, timeouts all happen asynchronously.
-
Santosh Singh over 4 yearsAs you mentioned above that javascript is asynchronous --- it's not correct. Its mainly synchronous and for cases it's asynchronous. stackoverflow.com/questions/2035645/…
-
Shubham Khatri over 4 years@santoshsingh. Ohh that was a mistake on my part. Didn't form the sentence correctly
-
user1204214 over 4 yearsvery clever use of the callback to ensure the state is updated before the subsequent call!
-
Hasan Sefa Ozalp over 4 yearsThis does not work if you use
useState
hook in a functional component. UseuseEffect
instead for an effect after rendering. -
alex351 almost 4 yearsGreat, it works with useEffect. But why does it need one?
-
Siraj Alam almost 4 years
useEffect
runs on every re-render, and if the items passed into the array are state variable sand changed. So when the fruit changed and component re-renders, that useEffect will run. -
alex351 almost 4 yearsI run setFruit and console.log fruit outside of useEffect, and it does not change. :/
-
notacorn almost 4 yearsTHANK YOU this is it, you have to directly set the variable
-
Hem M over 3 yearsI had completely forgot the fact that it's async call and did all possible code changes except for this one and here you saved my brain from burning out. thanks
-
thargenediad over 3 yearsThis solved my issue, but I put the setState() inside of the setTimeout() instead. Thank you!
-
ggorlen almost 3 years
setState
doesn't return a promise, so I don't expect this to work. -
Ethicist over 2 yearssetting the state like this fixed it for me
-
Kacper Kwaśny over 2 yearsI never see the output, in addition the key which I was trying to update becomes undefined.
-
Gavin over 2 yearsThanks for leaving this. Your comment pointed me in the right direction. I found the problematic code being updated in a conflicting event, then in that spot I used prevState callback to set new state as mentioned above by @Arun Gopalpuri ``` this.setState(prevState=>{ return {...prevState, newProperty }}); ```
-
Omar Dulaimi over 2 yearsThanks a lot man. You just saved me from even more debugging.