0

Consider the program below, when it is run in its current form it never displays "here" to the screen however if the fourth line is commented out then it does. it is my understanding that setState is asynchronous however I would imagine that when var is eventually set to true the while loop will end.

To be clear, this is how I understand what is happening:
The component is created, immediately componentDidMount is called, then this.setState({var: true}) is called. This is done asynchronously so the program splits into two "paths", the first continues on to the while loop where it gets stuck, the second changes var from false to true. Once var is changed from false to true the the first path should break out of the while loop and the second path should end because the asynchronous call is complete. However this is not what happens which is what I find confusing.

export default class Test extends Component {
    constructor(props){
        super(props)
        this.state = {var: false}; // consider removing this line
    }

    componentDidMount(){
        this.setState({var: true})
        while (this.state.var == false){}
    }

    render(){
        return(<View style={{padding: 30}}><Text>Here</Text></View>)
    }
}

Thanks for the help

Mathew
  • 1,116
  • 5
  • 27
  • 59

1 Answers1

0

componentDidMount is called after an initial render call which is called after the constructor is called.

Study this react lifecyle diagram.

In your example the constructor sets initial state (var: false), so when componentDidMount is finally called this.state.var == false evaluates to false == false => true thus yielding you an infinite loop. This infinite loop prevents React from actually setting the new state since setState is an asynchronous function. When you comment out the fourth line, then this.state.var is actually undefined, so undefined == false => false, no looping. It's confusing because you have it 100% reversed.

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
  • 1
    but why doesn't `this.setState({var: true})` first change var to true? – Mathew Jun 28 '18 at 06:22
  • Because `setState` is an asynchronous function, so you can't depend on any state values set immediately after the line containing the `setState` call since React controls when it's actually set. You can, however, use a `setState` callback to use guaranteed values **after** the state was set. `this.setState({var: true}, () => console.log(this.state.var));` will show the updated state value. Read up on the [setState](https://reactjs.org/docs/react-component.html#setstate) lifecycle function. – Drew Reese Jun 28 '18 at 06:49
  • I edited my answer to reflect the asynchronous nature of React's `setState` lifecycle function to specifically address why your code snippet didn't work. – Drew Reese Jun 28 '18 at 06:56