The use Hook in React 19

The use Hook in React 19

What Is the use Hook?

The use hook is a new React API that lets you read values from resources like Promises or contexts.

Its basic syntax is:

const value = use(resource);

Key Differences from Traditional Hooks

Unlike traditional React hooks (like useState or useEffect), the use hook has some important differences:

  1. Can be used in conditionals and loops: While regular hooks must be called at the top level of your component, use can be called inside if statements, loops, and other conditional code.

  2. Multi-purpose functionality: It works with different types of resources (Promises and contexts).

  3. Integrates with Suspense: When used with Promises, it automatically works with React's Suspense system.

Using use with Context

When working with context, use serves as a more flexible alternative to useContext:

function Button() {
  // This works even inside conditionals!
  if (someCondition) {
    const theme = use(ThemeContext);
    return <button className={theme}>Click me</button>;
  }
  return <button>Default</button>;
}

The use hook searches up the component tree just like useContext to find the nearest context provider.

Using use with Promises

The most powerful aspect of use is its ability to work with Promises, especially in the context of Server Components:

function MessageComponent({ messagePromise }) {
  // This unwraps the Promise value
  const message = use(messagePromise);
  return <p>{message}</p>;
}

When use is called with a Promise:

  • The component "suspends" while the Promise is pending

  • When the Promise resolves, the component renders with the resolved value

  • If the Promise rejects, the nearest Error Boundary will catch the error

This is particularly useful in the Server Components pattern, where a Server Component fetches data and passes the Promise to a Client Component:

// Server Component
export default function App() {
  const messagePromise = fetchMessage();
  return (
    <Suspense fallback={<p>Loading...</p>}>
      <MessageComponent messagePromise={messagePromise} />
    </Suspense>
  );
}

// Client Component
("use client");
function MessageComponent({ messagePromise }) {
  const message = use(messagePromise);
  return <p>{message}</p>;
}

Error Handling with use

There are two main ways to handle errors when a Promise passed to use rejects:

  1. Error Boundaries: Wrap the component in an Error Boundary to show a fallback UI when errors occur
<ErrorBoundary fallback={<p>Something went wrong</p>}>
  <MessageComponent messagePromise={messagePromise} />
</ErrorBoundary>
  1. Promise.catch: Provide an alternative value if the Promise rejects
const safePromise = fetchData().catch(() => "Default value");
// Later in component
const data = use(safePromise); // Will be "Default value" if the Promise rejects

Important Limitations

  • You cannot call use in a try-catch block

  • use must be called inside a Component or Hook function

  • When passing Promises from Server to Client Components, the resolved value must be serializable

When to Use use vs. Alternatives

  • Use use(context) instead of useContext when you need conditional context access

  • In Server Components, prefer async/await over use for data fetching

  • In Client Components, prefer consuming Promises passed from Server Components with use rather than creating new Promises