0
class Hello extends React.Component {
    constructor(props){
        super(props)
            this.state={count:1};
            this.myRef = React.createRef();
        }
        use(){
            console.log(this.myRef);
            let f=function(){
            this.setState({count:2});
            console.log("in f" + this.state.count);
        }
        //let a=React.findDOMNode(this.myRef.current);
        this.myRef.current.onclick=f.bind(this);
        //console.log(a);
    }

    render() {
        console.log("in render"+" "+this.state.count);
        return (
            <div>Hello {this.state.count}
                <div onClick={this.use.bind(this)}>add function</div>
                <button ref ={this.myRef}>click</button>
            </div>;
        )
    }
}

ReactDOM.render(
  <Hello name="World" />,
  document.getElementById('container')
);

In this code 'console.log("in f" + this.state.count)' is executing after 'console.log("in render"+" "+this.state.count)' that is possible only if setState is synchronous function call that internally calls another synchronous function render.But according to reactjs setState is asynchronous ,so 'console.log("in f" + this.state.count)' should be executed first.Why it is behaving like this?

adityajain019
  • 72
  • 1
  • 7

1 Answers1

0

This is related to batched updates. In the code above, f event listener is added manually, click event is triggered outside React lifecycle. State updates aren't batched but occur synchronously. This may affect the performance in negative way, in case state updates could benefit from batching.

Here are simpler examples that show how it works.

Example 1

State update happens inside React lifecycle, it is batched and asynchronous.

  f = () => {
    this.setState({count:2});
    console.log("in f" + this.state.count);
  }

  render() {
    console.log("in render"+" "+this.state.count);

    return <div>
      Hello {this.state.count}
      <button onClick={this.f}>click</button>
    </div>;
  }

The output is:

in f1

in render 2

Example 2

State update happens outside React lifecycle, it's unbatched and synchronous.

  f = () => {
    setTimeout(() => {
      this.setState({count:2});
      console.log("in f" + this.state.count);
    })
  }
  ...

The output is:

in render 2

in f2

Example 3

State update is again batched and asynchronous.

  f = () => {
    setTimeout(() => {
      ReactDOM.unstable_batchedUpdates(() => {
        this.setState({count:2});
        console.log("in f" + this.state.count);
      });
    })
  }
  ...

The output is:

in f1

in render 2


As for findDOMNode, it's related to DOM, as the name suggests. It's ReactDOM.findDOMNode, not React.findDOMNode.

Estus Flask
  • 206,104
  • 70
  • 425
  • 565