1

I am building a React app and I have a code following this logic:

class ComponentTest extends Component {
  state = {test: 0}

  testingHandler = () => {
     console.log(this.state.test)
  }

  updateHandler = () => {
     let test = Math.random()  
     this.setState({test})
     this.testing()
  }
        
  render () {
     return (
        <button onClick={this.updateHandler}>Update</button>
     )
  }
}

What I need to do is get the updated value of test in testingHandler(), however it doesn't happen, testingHandler just get the past value, it is like the state that is being received by testingHandler is always one step late.

For example, let's say that test = 0, then I click on the button that calls updateHandler() and now test = 1, after that updateHandler() calls testingHandler(), which I expect to get the new value of test which now is 1, however I get the old value 0. If I call updateHandler() again and update test to 2 I'll get 1 in testingHandler(), which is the past value.

How can I get this value updated from testingHandler?

I did everything that I could imagine, but I couldn't get this done. I believe it has something to do with the render logic of React, but I don't know exactly how this is working.

P.S. Passing the value as an argument is not an option.

Berg_Durden
  • 1,531
  • 4
  • 24
  • 46

3 Answers3

2

setState is asynchronous.

React may batch multiple setState() calls into a single update for performance.

Because this.props and this.state may be updated asynchronously, you should not rely on their values for calculating the next state.

You can pass a callback function as the second argument of setState that will run right after the state has updated. So in you case, you could do this:

  updateHandler = () => {
     let test = Math.random()  
     this.setState( {test}, this.testingHandler )
  }
Seth Lutske
  • 9,154
  • 5
  • 29
  • 78
1

copied from react documentation link: https://reactjs.org/docs/faq-state.html

Calls to setState are asynchronous - don’t rely on this.state to reflect the new value immediately after calling setState. Pass an updater function instead of an object if you need to compute values based on the current state

better you can pass it as a callback function or you can also pass the value to the function.

This link is also helpful: setState doesn't update the state immediately

KushalSeth
  • 3,265
  • 1
  • 26
  • 29
1
  class ComponentTest extends Component {
    state = { test: 0 };

    testingHandler = () => {
      console.log(this.state.test);
    };

    updateHandler = () => {
      let test = Math.random();
      this.setState({ test }, () => this.testingHandler()); // pass it as a callback
     
    };

    render() {
      return <button onClick={this.updateHandler}>Update</button>;
    }
  }
SakoBu
  • 3,972
  • 1
  • 16
  • 33