Understanding state scheduling and batching in React

We know how React manages state, or at least we have an idea, but there's one thing which is important: and that is how React handles state updates. In your code, you might have a component and in that component, you might manage some state with the help of the useState hook and therefore React manages that state for you.

Let's say that we have a product component with the current state 'DVD', so we have 'DVD' as a product. Now eventually, because a user clicked a button or whatever, in that component we update that state, for example with setNewProduct('Book') that could be our state updating function returned by the useState hook and we set the new product to book, so from 'DVD' to 'Book'. Now what happens with that is not that 'DVD' is instantly set after setNewProduct finishes execution is replaced. Calling those state updading functions in general schedules a state update with the data 'Book'.

But that's now a scheduled state change and React is aware of it, React plans on processing it and React doesn't process that immediately though. Now in reality most of the time, state changes and scheduled state changes will be processed very fast, pretty much instantly. So in reality, it might feel instant. If we click a button and that removes a paragraph to us as a human, that happens instantly. But React reserves the right of actually postponing that state change because for example a lot of other performance intensive tasks are going on at the same moment, potentially it asks that, React considers to have a higher priority. Let's say on your screen, you have a input field where the user is able to type something. React to that user input would have a higher priority than changing some text on the screen. For reasons like that, React might postpone scheduled state changes. Now, what React does is, it guarantees you that the order of state changes for one in the same type of state is guaranteed.

So if we call setNewProduct again and we set this to something else, for example setNewProduct('Carpet'), then this state change would not be performed before the previous state change. So the order is kept, but it's not necessarily executed immediately. Eventually of course it will be oricessed and your new state will be 'Book' and one that new state is active, once that state change was processed, React will reevaluate the component, it will re-run the component function. Now because of that scheduling where of course you might have multiple outstanding scheduled state changes at the same time, because of that, because multiple updates can be scheduled at the same time, because of that, it is recommended to use the following format to update the state:

setNewProduct((prevProduct) => newValue);

In a lot of cases this will probably not matter because it's processed so quickly taht you can't even click fast enough to see a delay but because it theoretically could be postponed, this is the safe way of ensuring that state changes are processed in order and for every state change where you depend on the previous state, you get the latest state. Otherwise you might just get the latest state when the component function was executed last, which os not necessarily the same state as if the state changes are executed in order. Because if you have multiple outstanding state changes, they all come from the same last re-render cycle of the component. They all come from the last component snapshot, but of course, if they were processed, the component would re-render in between but since they're all already scheduled, all outstanding state changes don't take the new in-between component result into account.

You can have multiple outstanding state changes from one and the same component re-evaluation. So the state updates scheduling is a mechanism you have to keep in mind, not because you actively need to do something about that because React manages those scheduled updates for you, but because you need to write your code accordingly to rule out any danger of potentially working without data.

Now there is another important thing you need to know about React: if you update a state, the state is not available with the new value in the next line, every time. Instead, the update will be scheduled and eventually the entire component will rerun and then after the componet rerun we have the latest state value available, not earlier. If you have two state updates in the same synchronous code snippet after each other so not in a promise in different blocks but in the same function, for example, where nothing in between would cause a time delay or anything like that, so the lines are after each other, in such cases, React will batch those state updates together in one long synchronous process, so for example, in one function that executes start to end without any callbacks or promises in between, in such cases React will take all the state updates that are produced by that function and it will batch them together into one state update.

Category: React Tags: #react, #performance