Other

use

Reads a resource such as a Promise or Context. Unlike other hooks, use can be called inside loops and conditional statements. The only hook that can consume Promises directly (React 19+).

Signature

TypeScript
const value = use<T>(resource: Promise<T> | React.Context<T>)

Parameters

ParameterTypeDescription
resourcePromise<T> | React.Context<T>A Promise to read a value from (suspends the component until it resolves), or a Context to read the current value from.

Return Value

The resolved value of the Promise, or the current value of the Context. When reading a Promise, the component suspends until the Promise resolves.

Examples

Reading a Promise
import { use, Suspense } from 'react';

async function fetchUser(id: string) {
  const res = await fetch(`/api/users/${id}`);
  return res.json();
}

function UserProfile({ userPromise }: { userPromise: Promise<{ name: string; bio: string }> }) {
  const user = use(userPromise);

  return (
    <div>
      <h2>{user.name}</h2>
      <p>{user.bio}</p>
    </div>
  );
}

function Page({ userId }: { userId: string }) {
  const userPromise = fetchUser(userId);

  return (
    <Suspense fallback={<p>Loading user...</p>}>
      <UserProfile userPromise={userPromise} />
    </Suspense>
  );
}
Conditional Context Reading
import { use, createContext } from 'react';

const ThemeContext = createContext<'light' | 'dark'>('light');
const AdminContext = createContext<boolean>(false);

function StatusBadge({ showTheme }: { showTheme: boolean }) {
  const isAdmin = use(AdminContext);

  // Unlike useContext, use() can be called conditionally
  let theme = 'light';
  if (showTheme) {
    theme = use(ThemeContext);
  }

  return (
    <span style={{
      background: isAdmin ? 'gold' : 'gray',
      color: theme === 'dark' ? 'white' : 'black',
      padding: '2px 8px',
      borderRadius: 4,
    }}>
      {isAdmin ? 'Admin' : 'User'}
    </span>
  );
}
Promise with Error Boundary
import { use, Suspense } from 'react';
import { ErrorBoundary } from 'react-error-boundary';

function Comments({ commentsPromise }: {
  commentsPromise: Promise<{ id: string; text: string }[]>;
}) {
  const comments = use(commentsPromise);

  return (
    <ul>
      {comments.map(c => <li key={c.id}>{c.text}</li>)}
    </ul>
  );
}

function PostPage({ postId }: { postId: string }) {
  const commentsPromise = fetch(`/api/posts/${postId}/comments`).then(r => r.json());

  return (
    <ErrorBoundary fallback={<p>Failed to load comments.</p>}>
      <Suspense fallback={<p>Loading comments...</p>}>
        <Comments commentsPromise={commentsPromise} />
      </Suspense>
    </ErrorBoundary>
  );
}

Common Pitfalls

!

Creating a new Promise on every render — the Promise must be created outside the component or cached, otherwise it triggers infinite suspense loops.

!

Not wrapping the component in a <Suspense> boundary when reading Promises — the component suspends and needs a fallback.

!

Not wrapping in an ErrorBoundary — rejected Promises throw and need to be caught.

!

Trying to use() a Promise from a client-side fetch without proper caching — use a framework or cache library to avoid re-fetching.

Understanding use

use is a unique React 19 API that breaks the traditional rules of hooks — it can be called inside loops, conditionals, and early returns. This flexibility makes it fundamentally different from other hooks and opens up new patterns for reading asynchronous data and context values. It serves two purposes: reading Promises and reading Context.

When used with a Promise, use suspends the component until the Promise resolves, integrating with React's Suspense system. The component "pauses" and shows the nearest Suspense boundary's fallback until the data is ready. This is React's recommended approach for data fetching in modern applications, replacing the pattern of useEffect + loading state for many use cases. The key requirement is that the Promise must be stable — created outside the component, in a parent, or cached by a framework.

When used with Context, use behaves similarly to useContext but with the critical advantage of conditional calling. You can read different contexts based on conditions, use context values inside loops, or skip context reads entirely based on props. This flexibility is impossible with useContext due to the rules of hooks requiring consistent call order.

The Promise integration works hand-in-hand with React Server Components and frameworks like Next.js. A Server Component can start a data fetch and pass the Promise as a prop to a Client Component, which reads it with use. This pattern enables streaming — the server sends the shell immediately and streams in data as it resolves. Combined with Suspense boundaries at different levels, you can create sophisticated loading states that progressively reveal content as data arrives.

Related Hooks

More Other Hooks

Explore All React Hooks

Browse our complete reference of 19 React hooks with signatures, examples, pitfalls, and in-depth explanations.