In all versions, till React 18 the rendering was always synchronous. That means when React started rendering a component it couldn’t be interrupted or aborted. With the concurrent rendering, we have another situation, because React can actually stop and continue it later or even abort the whole process.
Having that cool new implementation we are able to develop a more smooth and more fluid UX. In other words, concurrency is the ability to provide several tasks at the same time. So it allows for preparing lots of instances of the UI simultaneously or concurrently.
In order to understand it better, let’s look at the following example.
Here we have an array with numbers from 0 to 19.999 which are displayed on the list of UI. In addition to this, our UI has a textbox that lets us filter all the numbers. As far as the array has 20.000 elements the filtering will be time-consuming here. So, each time we type a number we receive a lag in its appearance in the textbox because the rendering takes a lot of time. In that way, the only solution for us is to postpone the filtering process and allow the text we type to occur directly. And that is where we need the concurrency because we can stop or cancel the rendering that works over the number filtering and give the priority to updating the textbox state.
In order to notify React about some state change that may cause an expensive rendering, we can use the useTransition() hook. In that way, React will make the priority of the chosen element lower, and that will allow other renderings to work faster and ensure a responsive and much more adaptable UI. The expensive renderings are sometimes called transition updates and those that are to be executed at once are called urgent updates.
As a rule, such actions as clicks, pressing, and typing are considered to be urgently updated because they have to provide the response at the moment they occur. In that way, a smooth UX can be provided.
Usually, each change of state is supposed to be an urgent update and we can specify it when utilizing the useTransition() hook. When we call it, we receive an array with two elements: the boolean value isPending and the method called startTransition().
What is isPending?
isPending is the boolean value that identifies if the low-priority state updates are still pending or not.
Although you wait for the update of the main state to finish, you could use isPending and update the UI to display some backup material as in the code below.
What is startTransition()
startTransition() is the method that takes a callback that is responsible for the state or transition update and makes its priority lower to be executed after the urgent updates. In that way, the urgent updates won’t lag anymore and provide a better UX as well.
This hook is rather similar to useTransition() in functionality. The main difference between them is if useTransition() notifies React about some setState method will cause a transition update then useDefferedValue tells React about the received value that will cause that transition update.
To be more clear, useTransition() works with state change, useDefferedValue() works with a received value.
You may ask why we need them if they generally do the same thing. It’s clear. Sometimes we have no access to the setState method and here useDefferedValue() can be useful that will take the passed prop value that causes a transition update and tells React about it.
All we need to do is to pass the prop value as an argument to useDefferedValue() and use the returned value in a component. In such a way, React will do the same action as with useTransition(). It will treat the expensive rendering as low-priority and make the urgent updated take place first.
When useTransition() and useDefferedValue() should be used?
Such hooks as useTransition() and useDefferedValue() shouldn’t be used everywhere in your code. We must utilize them only in cases when we have some complex UI and such means as pagination, lazy loading, worker threads, and so on. Moreover, you have to keep in mind that there is no need to use them both. Usually, useTransition() is enough because it wraps the updating code and when you can’t control the setState, only then useDefferedValue() to get the value received from the state change and make a low-priority component.
New hooks and functionality in ReactJS make us much better developers and allow us to create robust and great React apps faster and with higher quality. We as a custom software development company that develops CRM systems, websites, and apps know well all the benefits that ReactJS gives us. And we use them at the full range to create great products for our customers. So if you need a high-end service or a good ReactJS developer, turn to us, and we will help you gladly.
Don't want to miss anything?
Get weekly updates on the newest design stories, case studies and tips right in your mailbox.