Concurrency and Transitions in React

One of the biggest updates in React 18 is that it supports concurrency. Let’s look at what that means first before we jump into the specific features. By definition concurrency is:

Judy@webdecoded
4 min readJun 7, 2022

the ability of different parts or units of a program, algorithm, or problem to be executed out-of-order or in partial order, without affecting the final outcome.

Skeleton Screen Gleam Animation

Meaning one process, for example, a state update can start and pause at any time to continue another process or make both happen simultaneously, versus previously in React we had Block Rendering, enabling it to only handle one task at a time.

To understand how to make use of this concept, we have to first get the problem it solves.

The Problem Concurrency Solves

Stop and continue processes based on the NEED, and not based on times set in debounce or other events to finish to start computing when computing can be done in the background when other events progress. This makes the app more responsive.

Why we need to debounce or throttle in the first place?

Let’s say we have a search bar, where users can type in and filter data. If we make updates to the list on every key stroke, then the component would get re-loaded(making it slower) and we would have to make computations(an API call or filtering on the client side) on every version of the text input that user enters. For example, if a user puts ‘s’ we have to make a search on ‘s’ and by the time they have entered ‘se’ we might not be finished with getting results for the ‘s’ so after waiting for those results we will fetch new ones, eventually leading to delayed update of the results. Here’s an example, where the data is fetched from the API on everytext update and by the time this text is clear, the app is still processing results for the previous states and delivering the final results after it’s done with all state updates consecutively:

Crypto Coins Search using CoinGecko API

To make this experience faster, we would have used debounce or throttle, but they also introduce the slowness, because we artificially set an arbitrary amount of time to wait or the time needed to wait for the event, for example, the user waiting to finish typing, but then this means that the application is not that responsive while they are typing since results are not getting updated, the benefit of this approach is that our code runs less calculations and thus the results for the final state are delivered more abruptly. As you can see in this example, where the app skips calling API multiple times and only calls after the delay time that is set has passed:

CodeSandbox URL

But if we interrupted the calculation of the results for the previous state when we received the new state, then we would have a much smoother user experience. So to improve it, we need to determine which processes can be interrupted and which not. In other words, which are the urgent and less-urgent updates. That is where transitions come in.

Transitions

Urgent updates: typing, clicking, selecting

Transition updates: list update, tab content switch, more data load

Urgent updates should be happening immediately when user starts typing the input should get updated, the button should get focused on click and etc. Transition updates are ones that take more time and can be interrupted thus they will go into the concurrent rendering.

We declare what can be considered as a transition by wrapping it in the startTransition and rest of the changes can just be triggered as we used to do it previously.

import {startTransition} from 'react';

// Urgent: Show what was typed
setInputValue(input);

// Mark any state updates inside as transitions
startTransition(() => {
// Transition: Show the results
setSearchQuery(input);
});

We can also get the state of the transition, whether or not it is pending. The biggest use of this is displaying spinner in the UI. We can do this by using useTransition the hook:

const [isPending, startTransition] = useTransition();

References:

--

--

Judy@webdecoded
Judy@webdecoded

Written by Judy@webdecoded

Software Engineer | YouTuber | Web3 Enthusiast

No responses yet