This time, I’m going to walk you through the principle of setState that’s common in React.

The default behavior of setState itself

You definitely need to learn the basics of React before you can get into the main topic. If not, please like to leave; If you use React, favorit for one item and leave (●’ plump ‘●).

We use state a lot when we use React, but there are very few people who can figure out setState completely. After all, programmers are unlikely to be as knowledgeable (and good-looking) as I am. So, to figure it out, should you go to reincarnation (plastic surgery)?

No, you need to figure out the default behavior of setState itself.

It’s very simple. As we all know, setState can pass state as an object or as a function. Regardless of whether the state is in object or functional form, it saves all the states first, then merges them, and then makes a one-time DOM update once all the states are merged.

If the state is in the form of an object, the later state directly overrides the previous state. Merge operation similar to object.assign ().

For object state, let’s call cui Hua.

Run the code, and the result displayed in the Dom is 1. Obviously, only one of the two setstates is valid.

Is it true? Both sets work, but the two setstates are merged into one before being executed. You can’t say which one is in effect, you can say neither is in effect, because the code that was merged was executed.

If the state is in the form of a function, the state is accumulated by calling functions in turn, and after all the function calls are complete, the final state is obtained, and finally a one-time DOM update is made.

Cui flower, another code…

A significantly different result would indicate that both were executed, because the state of the function does not merge, but instead runs in this way.

Ok, cui hua can go down to rest first, but we have already combed through, so, for setState research is finished? Of course not. Next, let’s go through a different court and battle.

SetState Synchronous OR asynchronous

In an interview scenario, anything related to React, the interviewer will lick your face and ask you, “Bao Zi, is setState synchronous or asynchronous?”

In the face of such shameless, we need to be clear, from the API level, it is a normal call to execute the function, naturally synchronous API.

Therefore, by synchronous and asynchronous, I mean whether the DOM is updated synchronously or asynchronously after an API call.

Come on, let’s have Natasha, code up…

Sure enough, the code that the foreign girl serves up is really not easy to digest, through the result we find that a very strange phenomenon:

The first execution of the event is obviously asynchronous. Two zeros are printed, and the Dom changes to 1.

The second time is also asynchronous, but we find that multiple executions have no effect. ;

The third time it was executed synchronously;

What’s going on here? Did the foreign girl drug us? Watch me break it.

First of all, synchronization and asynchrony depend on the context in which it is invoked.

  • If setState is called in a range that React can control, it is asynchronous. For example, the composite event handler, the lifecycle function, will be batch updated, that is, the state will be merged before DOM update.

  • If setState is called within the scope of native JavaScript control, it is synchronous. For example, in native event handlers, timer callbacks, and Ajax callbacks, setState updates the DOM as soon as it is called.

Why is that?

In fact, the so-called “asynchrony” we see is the “batch update” mode enabled.

Batch update mode can reduce the number of real DOM rendering times, so as long as React can control the scope, due to performance factors, batch update mode must be. Batch updates merge the status first and then do a DOM update all at once.

What if there were no batch updates?

From the perspective of life cycle, each setState is a complete update process, which includes many operations including re-render. The general process is as follows:

ShouldComponentUpdate - > componentWillUpdate - > render - > componentDidUpdate;Copy the code

Re-render itself involves manipulating the DOM, which has a significant performance overhead. If “a setState triggers a complete update process” is true, then every call to setState triggers a re-render, and our view is likely to get stuck after only a few refreshes.

Thus, an important motivation for setState asynchrony (or batch updating) is to avoid frequent re-render.

In the actual React runtime, setState asynchrony is implemented a bit like event-loop in the browser:

Every time you get a setState, you shove it into a queue. When the time is ripe, the state results in the queue will be merged, and finally only the latest state value will be updated once.

This process is called “batch update” and the batch update process is shown in the arrow diagram in the code below:

As long as our synchronization code is executing, the “enqueue” action will not stop. Therefore, even if we write a setState loop N times in React, it will only increase the number of state tasks queued, and will not cause frequent re-render. After N calls, only the contents of the state task queue have changed, but the state itself does not change immediately.

To better help you eat Natasha’s — no, natasha’s — dishes, LET me help you to run through the process of setState:

Of course, you may not understand this flow chart (how stupid is that?), but there will be more.

In non-batch update mode, the real DOM is rendered as many times as setState is called, with poor performance.

However, we need to implement batch update (asynchronous update DOM) to JS controlled areas under certain conditions, so what should we do?

Force batch update

It’s really easy. I’m too embarrassed to say it’s so damn easy.

To force batch updates, wrap the code in a callback function to the unstable_batchedUpdates method.

The way to use it is very simple, just import it from the React-DOM and put the code into the calling function.

(Cui hua and Natasha married, I will give you the code)

Up to now, we have made a perfect love, ah, bah

To be continued…