1

Consider example:

state = { x: false };

x = () => {
   this.setState({ x: true });
};

y = async () => {
   await this.x();
   console.log(this.state.x);
   ^^^^  // logs true if used with await, logs false if await removed
};

y();

Since setState is async, the state update should happen after console.log, so false should be logged. And so it does.

HOWEVER!

If I use an async func and AWAIT the this.x(), the true value is being logged. How? Why?

Playground: https://stackblitz.com/edit/react-13fhfd?file=src%2FApp.js

Patrickkx
  • 1,740
  • 7
  • 31
  • 60

1 Answers1

1

Here is my take on what is happening. Someone with more experience about the execution engine internals may have a more accurate answer, but I'm trying to think on a high level.

When we use the await keyword, it waits on a promise (if the expression is not a promise, then it is automatically wrapped around a promise.resolve()).

So here what is happening is that x() runs, and it calls this.setState which is async, so it goes into the event loop. Once that returns, the await keyword wraps that into another promise, which then goes into the event loop. setState is thus further ahead in the event loop, and hence gets executed first. Once that promise resolves, we move ahead to the console.log, and by then the value for state has changed.

Kenny John Jacob
  • 1,188
  • 8
  • 21