React setState not updating state

275,849

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)
)}
Share:
275,849
The worm
Author by

The worm

Updated on July 08, 2022

Comments

  • The worm
    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. however this.state.dealersOverallTotal does not give the correct total but total does? I even put in a timeout delay to see if this solved the problem. any obvious or should I post more code?

    • Assan
      Assan over 7 years
    • Felix Kling
      Felix Kling over 7 years
      Besides what is said in the answers, you are explicitly logging the value of the state, before you are calling setState.
    • The worm
      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
      Fabian Schultz over 7 years
      Because of the timeout your setState is indeed executed after you log the state. I think what you meant to do in debugging was putting the console.log part inside the timeout, and the setState outside.
    • The worm
      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
      Fabian Schultz over 7 years
      Can't reproduce it, maybe ask as a seperate question.
    • ggorlen
      ggorlen almost 3 years
      Does this answer your question? setState doesn't update the state immediately
  • Felix Kling
    Felix Kling over 7 years
    In addition to that, the OP explicitly logs the state value before they call setState.
  • Jozcar
    Jozcar almost 7 years
    This 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
    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
    Johncy over 5 years
    imgur.com/Ku0OjTl Please tell me what should i do to get rid of this problem.
  • Santosh Singh
    Santosh Singh over 4 years
    JavaScript is always synchronous.
  • Shubham Khatri
    Shubham Khatri over 4 years
    @santoshsingh you have a misconception. API calls, timeouts all happen asynchronously.
  • Santosh Singh
    Santosh Singh over 4 years
    As 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
    Shubham Khatri over 4 years
    @santoshsingh. Ohh that was a mistake on my part. Didn't form the sentence correctly
  • user1204214
    user1204214 over 4 years
    very clever use of the callback to ensure the state is updated before the subsequent call!
  • Hasan Sefa Ozalp
    Hasan Sefa Ozalp over 4 years
    This does not work if you use useState hook in a functional component. Use useEffect instead for an effect after rendering.
  • alex351
    alex351 almost 4 years
    Great, it works with useEffect. But why does it need one?
  • Siraj Alam
    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
    alex351 almost 4 years
    I run setFruit and console.log fruit outside of useEffect, and it does not change. :/
  • notacorn
    notacorn almost 4 years
    THANK YOU this is it, you have to directly set the variable
  • Hem M
    Hem M over 3 years
    I 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
    thargenediad over 3 years
    This solved my issue, but I put the setState() inside of the setTimeout() instead. Thank you!
  • ggorlen
    ggorlen almost 3 years
    setState doesn't return a promise, so I don't expect this to work.
  • Ethicist
    Ethicist over 2 years
    setting the state like this fixed it for me
  • Kacper Kwaśny
    Kacper Kwaśny over 2 years
    I never see the output, in addition the key which I was trying to update becomes undefined.
  • Gavin
    Gavin over 2 years
    Thanks 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
    Omar Dulaimi over 2 years
    Thanks a lot man. You just saved me from even more debugging.