Dickens
Dickens

Reputation: 915

Since setState is asynchronous, is it executed via callback queue?

I am new to React and was learnig how setState works behind the scenes. Thus I would like to ask some questions on it. Firstly, is setState always asynchronous? if not in what general situations it is synchronous. Secondly, how asynchrony happens in setState is it executed via web api and then callback queue? Guys if something is not clear please let me know. I just really need your help.

Upvotes: 6

Views: 1452

Answers (3)

tarzen chugh
tarzen chugh

Reputation: 11257

React setState is not always asynchronous, it depends upon how state change was triggered.

1) Synchronous - If the action is outside of Reactjs world or if the state change was triggered by timer or user induced event handler, then reactjs can't batch updates and has to mutate the state immediately.

2) Asynchronous If the state change is triggered by onClick, then Reactjs can batch updates to the state for performance gains.

Working codesandbox link

and

Reference post

import React from "react";
import ReactDOM from "react-dom";

import "./styles.css";

class App extends React.Component {
  state = {
    counter: 0
  };
  componentDidMount() {
    // const intervalId = setInterval(this.updateState, 5000);
    // this.setState({intervalId: intervalId});
    this.counter.addEventListener("mousedown", this.updateState);
  }
  componentWillUnmount() {
    this.counter.removeEventListener("mousedown", this.updateState);
    // clearInterval(this.state.intervalId);
  }
  updateState = event => {
    console.log("= = = = = = = = = = = =");
    console.log("EVENT:", event ? event.type : "timer");
    console.log("Pre-setState:", this.state.counter);
    this.setState({
      counter: this.state.counter + 1
    });
    console.log("Post-setState:", this.state.counter);
  };
  render() {
    return (
      <div className="App">
        <span onClick={this.updateState} ref={elem => (this.counter = elem)}>
          Counter at {this.state.counter}
        </span>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

console logs

    = = = = = = = = = = = =
    EVENT: mousedown 
    Pre-setState: 
    0
    Post-setState: 
    1
    = = = = = = = = = = = = 
    EVENT: click 
    Pre-setState: 
    1
    Post-setState: 
    1

As you can see in console logs, mousedown event state change is immediately reflected but onClick change is asynchronous or better said batched.

So its better we assume the state change will be asynchronous and use callback handler to avoid bugs. And off-course anything inside callback will go through event loop in javascript.

Hope that helps!!!

Upvotes: 2

Roopak Puthenveettil
Roopak Puthenveettil

Reputation: 1485

Yes. it's asynchronous. And in Javascript asynchronous actions are handled using event loop

https://www.youtube.com/watch?v=8aGhZQkoFbQ

Upvotes: 1

Jasper Bernales
Jasper Bernales

Reputation: 1681

Yes. it's always asynchronous and never synchronous. common mistakes by developers is something like this

 handleEvent(newValue) {
   this.setState({ value: newValue }, () => {
      // you can get the updated state here
      console.log(this.state.value)
   })
   this.doSomething(newValue)
 }

 doSomething(newValue) {
   // this.state.value is still the old value
   if (this.state.value === newValue) {
      // blabla
   }
 }

And you can't determine how much time it will take for the state to update.

Upvotes: 4

Related Questions