Capítulo 91 de 116

Chapter 91: use

Core Idea

use(resource) reads the value of a promise or a Context directly during render — unlike other Hooks, it can be called conditionally and inside loops, and reading a pending promise causes the component to suspend into the nearest Suspense boundary.

Key Concepts

  • Two resource types: use(promise) suspends the component until the promise resolves, then returns its resolved value directly (or throws if it rejects, catchable by an error boundary); use(SomeContext) reads a Context value, behaving like useContext but callable conditionally.
  • Not bound by the Rules of Hooks' "top level only" restrictionuse can be called inside if statements, loops, and after early returns, specifically because of how it integrates with Suspense/conditional data reading; this makes it structurally different from every other built-in Hook covered so far.
  • Reading a promise integrates with Suspense: a component calling use(promise) on a still-pending promise suspends exactly like a lazy-loaded component (Ch 87/70) — the nearest Suspense boundary's fallback shows until it resolves.
  • The promise itself typically comes from outside the component — often created in a Server Component and passed down as a prop, or from a Suspense-integrated data-fetching library — rather than created fresh inside the consuming component's render body (which would create an infinite loop of new pending promises on every render).
  • Complements useContext: for Context specifically, use gives the added flexibility of conditional reads that useContext doesn't allow, while behaving identically otherwise.

Code Examples

function Comments({ commentsPromise }) {
  const comments = use(commentsPromise); // suspends until resolved
  return comments.map(c => <Comment key={c.id} comment={c} />);
}
  • What it demonstrates: reading a promise passed down as a prop directly in render, suspending the surrounding Suspense boundary until it resolves rather than manually managing loading state.

Key Takeaways

  1. use is the one built-in Hook exempt from the "call only at the top level" rule — it can be conditional, which is central to how it's meant to be used.
  2. Never create the promise being read inside the same component's render body — pass it in from outside (a parent, a Server Component, a cache) to avoid an infinite pending-promise loop.
  3. For Context, prefer use over useContext specifically when you need to read it conditionally; otherwise they're interchangeable.

Connects To

  • Ch 70 (Suspense): the boundary that catches this Hook's suspension when reading a pending promise.
  • Ch 50 (useContext): the unconditional-only sibling for reading Context.
  • Ch 116 (Rules of Hooks): the general rule this Hook is a deliberate, documented exception to.