liveBook · Manning

useDeferredValue

As explained in React Hooks in Action: With Suspense and Concurrent Mode

useDeferredValue is a React Hook that returns a deferred version of a value so rendering based on it can lag behind more urgent updates.

useDeferredValue returns either the current value or its previous value, allowing urgent UI to update while rendering that depends on a slower value catches up. It works with Concurrent Mode and is useful when new data would otherwise replace usable content with a spinner. section 1.4.1 section 13.1.4

Use the hook by tracking a value and separating immediate rendering from potentially delayed rendering:

  • Call const deferredValue = useDeferredValue(value). The hook may return the new value when rendering succeeds immediately or the old value while React waits. section 13.1.4
  • Pass the current value to components that should respond immediately, and the deferred value to components that may suspend or take longer to render. section 13.1.4
  • Detect the temporary mismatch with const isPending = deferredValue !== value, then show a spinner or reduce opacity to signal stale content. section 13.1.4

Keeping user details visible during selection

When a Users page switches from Mark to Clarisse, UsersList receives the latest user immediately and can show inline progress. UserDetails receives deferredUser, so it continues showing Mark until Clarisse’s details finish rendering. Initialize defensively with const deferredUser = useDeferredValue(user) || user. section 13.1.4

Listing 13.6 Passing a deferred value to UserDetails
import {
  useState,
  unstable_useDeferredValue as useDeferredValue, 
  Suspense
} from "react";
 
// other imports
 
export default function UsersPage () {
  const [loggedInUser] = useUser();
  const [selectedUser, setSelectedUser] = useState(null);
  const user = selectedUser || loggedInUser;
  const queryClient = useQueryClient();
  const deferredUser = useDeferredValue(user) || user;                #1
 
  const isPending = deferredUser !== user;                            #2
 
  function switchUser(nextUser) {
    setSelectedUser(nextUser);                                        #3
 
    queryClient.prefetchQuery(/* prefetch user details */);
    queryClient.prefetchQuery(/* prefetch user image */);
  }
 
  return user ? (
    <main className="users-page">
      <UsersList
        user={user}                                                   #4
        setUser={switchUser}
        isPending={isPending}                                         #5
      />
 
      <Suspense fallback={<PageSpinner/>}>
        <UserDetails
          userID={deferredUser.id}                                    #6
          isPending={isPending}                                       #7
        />
      </Suspense>
    </main>
  ) : <PageSpinner/>;
}
#1 Track the user value: return the old if the new delays rendering.
#2 Create a pending flag that’s true if the deferred value is stale.
#3 Update the user value.
#4 Let the list know the new user.
#5 Let the list know its user is inconsistent with UserDetails.
#6 Show the old user details while waiting for the new.
#7 Let UserDetails know its user is stale.

Inspect the complete UsersPage wiring for immediate and deferred props, pending-state detection, and query prefetching. section 13.1.4

How React Hooks in Action: With Suspense and Concurrent Mode covers it

How deep it goes
Explains the old-versus-new decision, pending feedback, component placement, and a complete UsersPage example, but not implementation internals.
Examples
Uses a bookings Users page where a selected user updates immediately while a Suspense-wrapped details panel retains the previous user.
What it assumes
Assumes React component and Suspense knowledge while requiring Concurrent Mode setup through the experimental React release.
What you can do after
Apply it by passing current values to urgent components and deferred values to components that may suspend or render slowly.
How it connects
Connects useDeferredValue to Concurrent Mode, Suspense, useTransition, asynchronous data loading, and receded states.

Also explained in

Compare how 2 books explain useDeferredValue →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of React Hooks in Action: With Suspense and Concurrent Mode. The section links point to the parts of the book it draws on.