React Concurrent Mode - Revisited

Mar 5, 2020

React Concurrent Mode - Revisited

Understanding React Concurrent Mode & The Problems It Solves

Author

Aashish Tiwari
Aashish TiwariSenior Software Engineer - II

Concurrent Mode was announced about a year ago and is still an experimental feature that lets our app remain responsive in different network conditions and based on different device capabilities. Without any further ado, let's discuss the new features and concepts introduced in Concurrent Mode. We will discuss these features in the context of React and React apps:

1. Interruptible Rendering

Normally in React, if rendering begins and a user event occurs (like clicking a button), React will first complete the previous render and then process the user event. So, React uses blocking rendering, which can create some performance issues.

Concurrent Mode introduces the concept of interruptible rendering, so if rendering has started and a user event happens in between, React will stop the previous rendering, process the user event first, then continue the remaining part of the previous rendering. Concurrent Mode uses Time Slicing for interruptible rendering.

2. Data Fetching With Suspense

It works on a Render as you Fetch approach, which means that React starts loading the data without waiting for the component to load. Both the data and component start loading in parallel.

Here, we wrap our MySuspenseImage component in a Suspense component, which provides the fallback component until the image is loaded. We try to render MySuspenseImage even when imageData is not yet loaded. This makes MySuspenseImage suspend as a promise is thrown. The Suspense component catches the promise and shows the fallback component in the meantime. As soon as the promise resolves, it re-renders the image component. If any errors occur during data loading, they can be handled using the ErrorBoundary component.

3. SuspenseList

Suppose a page has multiple API calls. It’s likely their responses won’t come in the order required by the UI, which affects user experience. We can chain promises to maintain order, but that adds complexity.

SuspenseList solves this by providing a controlled loading sequence for different parts of the page. It wraps multiple Suspense components and uses the revealOrder property to control the order of reveal: 'forwards', 'backwards', or 'together'.

We can also control the number of loading indicators using the tail property, which can be 'hidden' or 'collapsed'. When tail is 'collapsed', only one loader is shown at a time.

In the example (shown in the GIF), with revealOrder='forwards' and tail='collapsed', first the user image is rendered, then user details, and finally user comments. This ensures smooth, sequenced UI loading. All async processes begin together, but the reveal order is controlled visually via SuspenseList.

4. useTransition Hook

Suppose you're on a fast connection and click your profile. You may transition instantly and see a loader for just 200ms, causing UI flicker. This can be fixed with complex logic, but the useTransition hook simplifies it.

It lets you wait on the current screen while new data loads, then transition smoothly.

The useTransition hook returns two values:

  • startTransition() – Handles the deferred state update.
  • isPending – A boolean that indicates if the data is still loading.

When a user clicks to navigate, React prepares the update in a separate branch while remaining on the current screen. If data loads quickly, it transitions early; otherwise, it waits for the defined timeout, then transitions. This reduces jarring screen transitions and flickering loaders.

You can see that the loader is shown on the previous screen while userDetails are fetched, then transitions smoothly to the new screen, loading the remaining data.

GitHub project link: https://github.com/Aashishgtbit/concurrent-react-example

References: https://reactjs.org/docs/concurrent-mode-intro.html

Thank you for reading!

Subscribe to Our Newsletter

More from the engineering frontline.

Dive deep into our research and insights on design, development, and the impact of various trends to businesses.
Insight
Building a Production-Ready Canva-like Editor with Konva.js, React 19 and Next.js 15
Sep 10, 2026

Building a Production-Ready Canva-like Editor with Konva.js, React 19 and Next.js 15

This blog explains how to build a production-ready canvas editor with Konva.js, React, and Next.js, covering architecture, performance, and key engineering decisions.

Insight
What a PHP-to-NestJS Banking Migration Taught Us About Architecture, Security, and Trust
Sep 8, 2026

What a PHP-to-NestJS Banking Migration Taught Us About Architecture, Security, and Trust

This blog explores the architecture, security, performance, and documentation lessons from migrating a legacy PHP/Laravel banking platform to NestJS.

Insight
Building Production-Grade Video Thumbnail Scrubbing in the Browser: HLS, Frame Extraction, Caching, and Performance Trade-offs
Sep 7, 2026

Building Production-Grade Video Thumbnail Scrubbing in the Browser: HLS, Frame Extraction, Caching, and Performance Trade-offs

This blog explains how to build responsive video thumbnail scrubbing in the browser for local files and HLS streams, covering frame extraction, caching, and performance trade-offs.

Insight
The Agent Can See Your App. How Often Can It Look?
Sep 4, 2026

The Agent Can See Your App. How Often Can It Look?

AI coding agents can now interact with mobile apps, but their effectiveness depends on iteration speed. This blog explores how React Native architecture influences feedback loops and AI-driven developer productivity.

Insight
Building Interactive Cards from Design JSON Without Killing Your Feed: Overlays, Video, Mute/Unmute, and Lag-Free Lists
Sep 1, 2026

Building Interactive Cards from Design JSON Without Killing Your Feed: Overlays, Video, Mute/Unmute, and Lag-Free Lists

Learn how to turn design JSON into interactive, video-enabled cards using overlays, smart media controls, caching, and virtualization without slowing down high-cardinality feeds.

Insight
The Bug That Doesn't Show Up in Code Review: Why Your Flutter Web App Reloads on Safari
Aug 19, 2026

The Bug That Doesn't Show Up in Code Review: Why Your Flutter Web App Reloads on Safari

A real-world look at how oversized images can trigger Safari reloads and iOS crashes in Flutter apps and how smarter image decoding prevents them.

Insight
From Prompting to Process: What Changed When Flutter Shipped Agent Skills
Aug 19, 2026

From Prompting to Process: What Changed When Flutter Shipped Agent Skills

This blog explores how Flutter Agent Skills improve AI-assisted development by combining official framework workflows with project-specific guidance for more consistent development.

The Right Conversation Can

Save You Six Months.

Book a call