Back to docsRecipe

React use hook patterns

The use hook unwraps Promises and context directly inside render. No more useEffect + useState boilerplate for async data.

Promise unwrapping

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

function Profile({ userId }: { userId: string }) {
  const user = use(fetchUser(userId));
  return <h1>{user.name}</h1>;
}

The component suspends until the Promise resolves. Wrap in a Suspense boundary for the loading state.

Context without useContext

const ThemeCtx = createContext("dark");

function ThemedButton() {
  const theme = use(ThemeCtx);
  return <button className={theme}>Click</button>;
}

use reads context conditionally — no Rules of Hooks violation inside early returns or loops.

Composing multiple resources

function Dashboard({ userId }: { userId: string }) {
  const user = use(fetchUser(userId));
  const posts = use(fetchPosts(userId));
  return <Feed user={user} posts={posts} />;
}

Each Promise resolves independently. The component renders once both are ready — no waterfall unless you chain them.

Key takeaway

use replaces the fetch-in-effect pattern. It integrates with Suspense for loading states and ErrorBoundary for failures. Use it when your data-fetching library returns a Promise — React 19 and Server Components make this the default mental model.