Concurrent React
Concurrent React is a set of new features that help React apps stay responsive and gracefully adjust to the user’s device capabilities and network speed. In this tutorial, we will focus on useTransition and useDeferredValue.
1. useTransition
The useTransition hook allows you to mark certain state updates as "transitions." Transitions are non-urgent updates that can be interrupted by more urgent updates (like typing or clicking).
JavaScript
import { useState, useTransition } from 'react';
function TabContainer() {
const [isPending, startTransition] = useTransition();
const [tab, setTab] = useState('about');
function selectTab(nextTab) {
startTransition(() => {
setTab(nextTab);
});
}
return (
<div>
<button onClick={() => selectTab('about')}>About</button>
<button onClick={() => selectTab('posts')}>Posts</button>
{isPending && <p>Loading...</p>}
{tab === 'about' && <About />}
{tab === 'posts' && <Posts />}
</div>
);
} 2. useDeferredValue
useDeferredValue allows you to defer re-rendering a non-urgent part of the tree. It is similar to debouncing or throttling, but it has the advantage that React will start the deferred render as soon as the urgent work is done.
JavaScript
import { useState, useDeferredValue } from 'react';
function SearchPage() {
const [query, setQuery] = useState('');
const deferredQuery = useDeferredValue(query);
return (
<div>
<input value={query} onChange={e => setQuery(e.target.value)} />
<SearchResults query={deferredQuery} />
</div>
);
} Key Differences
- useTransition wraps the code that performs the state update.
- useDeferredValue wraps a value that is affected by a state update.
Note: Concurrent features only work in Strict Mode and when using a compatible version of React (18+).