0

I have an example here with a simple state called counter. In the componentDidMount, I am getting 0 instead of 3 during console.log and during unmount, I am getting the counter number from button click instead of 0. I am confused as to how does it really works? Here is the code:

import React, { Component } from 'react'

class TestNumber extends Component {
    constructor(props) {
        super(props)
        this.state = {counter: 0}
    }

    componentDidMount() {
        console.log('Mount Called')
        this.setState({counter:3})
        console.log(this.state.counter)
      }
      
    componentWillUnmount() {
        this.setState({counter:0})
        console.log('Unmount Called')       
        console.log(this.state.counter)
      }

    handleClick = () => {
        this.setState({counter: this.state.counter + 1})
    }
    render() {
        return (
            <div>
                <h2>{this.state.counter}</h2>
                <button onClick={this.handleClick}>
                    Click me
                </button>
            </div>
        )
    }
}

export default TestNumber 
Nat
  • 679
  • 1
  • 9
  • 24

2 Answers2

1

In addition to posed answer.

The problem here is not with life cycle methods but the problem is state. In react state can be asynchronous sometimes.

React Doc: https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous

Supporting article: https://medium.com/@wereHamster/beware-react-setstate-is-asynchronous-ce87ef1a9cf3

In general we should assume that react state is asynchronous and should not rely on it immediately. Following code will print correct console.log.

this.setState({count: 3}, () => {
    console.log(this.state.counter)
});

Bottom line

React state can be asynchronous

Dnyanesh
  • 2,265
  • 3
  • 20
  • 17
0

It is not about how those two life-cycle methods work, it is about the setState being async in React, which means that the sate value won't be modified right after you call setState and that is why you get the old values from the console.log.

Why is setState in reactjs Async instead of Sync?

The following example will give you the right results.

    componentDidMount() {
        this.setState({counter:3}, () => {
            console.log(this.state.counter);
        });
        
        console.log(this.state.counter)
    }
      
    componentWillUnmount() {
        this.setState({counter:0}, () => {
            console.log(this.state.counter);
        });

        console.log('Unmount Called');      
    }
Martin
  • 1,763
  • 1
  • 13
  • 21