setState() is used in React to update the state of any component. Now setState() does not immediately mutate this state, rather it creates a pending state transition. Accessing state immediately after calling setState() can potentially return the existing value. There is no guarantee of synchronous operation on setState() and calls may be batched for perf gains.
Possible solution
We are used to calling setState with one parameter only, but actually the method’s signature supports two. The second argument that you can pass is a callback function, that will always be executed after the state has been updated (whether it is inside the React’s known context or outside it). An example might be:
To be politically correct, if you see the code inside the setState() function in React’s codebase, you will find that setState() is not at all an asynchronous function. As a method, it is always synchronous. It’s just that it calls enqueueState or enqueueCallback on updater behind the scenes, and thus its execution feels like it is async. Here is setState() directly taken from React’s source code
So, what’s actually sync or async are the effects of calling setState in a React application — the reconciliation algorithm doing the virtual DOM comparisons and calling render to update the real DOM.
Twist
However, if we use setState() as callbacks to functions like setTimeOut or AJAX calls, the state before and after are different, even if we don’t pass anything as a callback to setState(), like we did in the first example. But why is that?? Well, it turns out that React does not understand and thus cannot control code that doesn’t live inside the library. Timeouts or AJAX calls, for example are developer authored code, that gets executed outside the context of React.
So, why does React synchronously update state in these cases?
Well, it tries to be as defensive as possible. Not being in control means it is not able to do any performance optimisations and batching the updates. So, it’s better to update the state on spot and make sure the code that follows has access to the latest information available.
Gist
React batches updates and flushes it out once per frame (perf optimisation). However, in some cases React has no control over the batching, hence updates are made synchronously available, for example in AJAX, setTimeOut and similar web APIs.
Hope you all got to learn something new and interesting with this article.
Learn . Grow . Excel