Imagine a mission control center on a space station where hundreds of signals from different sensors are processed simultaneously. Some data is urgent (alarms), others less so (weather statistics from distant planets). React Concurrent Mode works on a similar principle - it allows you to prioritize interface updates so that the application remains responsive even during heavy operations.
Concurrent Mode is a set of mechanisms in React that allow interrupting and resuming rendering. Traditionally, React rendered synchronously - when it started an update, it had to finish it before it could react to anything else. In concurrent mode, React can:
It is like a space controller who can set aside analyzing data from a distant probe when a sudden alert about an approaching asteroid appears.
startTransition is an API that tells React: "this update is not urgent, you can interrupt it." It is ideal for operations that can wait a moment, like filtering a large list or navigating between tabs.1import { useState, startTransition } from 'react';
2
3function GalaxySearch() {
4 const [searchInput, setSearchInput] = useState('');
5 const [searchResults, setSearchResults] = useState([]);
6
7 const handleSearch = (value) => {
8 // Updating the input is URGENT - the user must see what they type
9 setSearchInput(value);
10
11 // Filtering results is LESS URGENT
12 startTransition(() => {
13 const filtered = galaxyDatabase.filter(
14 galaxy => galaxy.name.toLowerCase().includes(value.toLowerCase())
15 );
16 setSearchResults(filtered);
17 });
18 };
19
20 return (
21 <div>
22 <input
23 value={searchInput}
24 onChange={(e) => handleSearch(e.target.value)}
25 placeholder="Search galaxies..."
26 />
27 <GalaxyList results={searchResults} />
28 </div>
29 );
30}Thanks to
startTransition, the input responds immediately to typing, even if filtering thousands of galaxies takes a moment.useTransition is a hook that, in addition to startTransition, gives us an isPending flag indicating whether a transition is in progress:1import { useState, useTransition } from 'react';
2
3function MissionDashboard() {
4 const [activeTab, setActiveTab] = useState('overview');
5 const [isPending, startTransition] = useTransition();
6
7 const switchTab = (tab) => {
8 startTransition(() => {
9 setActiveTab(tab);
10 });
11 };
12
13 return (
14 <div>
15 <nav>
16 {['overview', 'crew', 'systems', 'navigation'].map(tab => (
17 <button
18 key={tab}
19 onClick={() => switchTab(tab)}
20 style={{
21 opacity: isPending && activeTab !== tab ? 0.7 : 1,
22 fontWeight: activeTab === tab ? 'bold' : 'normal',
23 }}
24 >
25 {tab.toUpperCase()}
26 </button>
27 ))}
28 </nav>
29
30 {isPending && <div className="loading-bar">Loading panel...</div>}
31
32 <TabContent tab={activeTab} />
33 </div>
34 );
35}Suspense is a component that allows you to "suspend" rendering until data is ready. Instead of manually managing loading states, you declare what to show while waiting:1import { Suspense } from 'react';
2
3function SpaceStation() {
4 return (
5 <div>
6 <h1>Space Station Alpha</h1>
7
8 <Suspense fallback={<LoadingSpinner message="Loading crew data..." />}>
9 <CrewList />
10 </Suspense>
11
12 <Suspense fallback={<LoadingSpinner message="Checking systems..." />}>
13 <SystemsStatus />
14 </Suspense>
15 </div>
16 );
17}Each section loads independently - the user sees the crew data as soon as it is ready, without waiting for the systems status.
The most common use of Suspense is loading components dynamically using
React.lazy:1import { lazy, Suspense } from 'react';
2
3// Dynamically loaded components
4const StarMap = lazy(() => import('./StarMap'));
5const MissionLog = lazy(() => import('./MissionLog'));
6const CrewManagement = lazy(() => import('./CrewManagement'));
7
8function CommandCenter() {
9 const [view, setView] = useState('map');
10
11 return (
12 <div>
13 <nav>
14 <button onClick={() => setView('map')}>Star Map</button>
15 <button onClick={() => setView('log')}>Mission Log</button>
16 <button onClick={() => setView('crew')}>Crew</button>
17 </nav>
18
19 <Suspense fallback={<div>Loading module...</div>}>
20 {view === 'map' && <StarMap />}
21 {view === 'log' && <MissionLog />}
22 {view === 'crew' && <CrewManagement />}
23 </Suspense>
24 </div>
25 );
26}We can nest
Suspense components, creating a loading hierarchy. The outer Suspense catches everything, while inner ones allow for more granular control:1function MissionControl() {
2 return (
3 <Suspense fallback={<FullPageLoader />}>
4 <header>
5 <MissionTitle />
6 </header>
7
8 <main>
9 <Suspense fallback={<SectionLoader text="Map..." />}>
10 <InteractiveStarMap />
11 </Suspense>
12
13 <aside>
14 <Suspense fallback={<SectionLoader text="Statistics..." />}>
15 <MissionStats />
16 </Suspense>
17
18 <Suspense fallback={<SectionLoader text="Messages..." />}>
19 <CommunicationLog />
20 </Suspense>
21 </aside>
22 </main>
23 </Suspense>
24 );
25}useDeferredValue is a hook that allows you to defer the update of a value. React first renders with the previous value (urgent update), then with the new one (less urgent):1import { useState, useDeferredValue, useMemo } from 'react';
2
3function PlanetExplorer() {
4 const [filter, setFilter] = useState('');
5 const deferredFilter = useDeferredValue(filter);
6
7 // The list renders with the deferred filter value
8 const filteredPlanets = useMemo(() => {
9 return allPlanets.filter(p =>
10 p.name.toLowerCase().includes(deferredFilter.toLowerCase())
11 );
12 }, [deferredFilter]);
13
14 const isStale = filter !== deferredFilter;
15
16 return (
17 <div>
18 <input
19 value={filter}
20 onChange={(e) => setFilter(e.target.value)}
21 placeholder="Filter planets..."
22 />
23 <div style={{ opacity: isStale ? 0.6 : 1 }}>
24 {filteredPlanets.map(planet => (
25 <PlanetCard key={planet.id} planet={planet} />
26 ))}
27 </div>
28 </div>
29 );
30}| API | Use case | Example | |-----|----------|---------| |
startTransition | Updates that can wait | Changing filters, navigating between tabs |
| useTransition | Same as above + loading indicator | Switching views with loading state |
| Suspense | Waiting for data or code | Lazy loading, data fetching |
| useDeferredValue | Deferring value rendering | Filtering large lists, search |Concurrent Mode and Suspense are like an advanced priority management system on a space station. Instead of processing all signals sequentially (blocking important alerts while analyzing less important data), React can intelligently prioritize updates:
These mechanisms work together, creating responsive interfaces even in complex applications with large amounts of data and heavy operations.