The use Hook

use reads a resource: a promise or a context. It breaks the usual hook rules — it may be called inside an if, inside a loop, or several times in one component — because it does not depend on call order. Given a promise it returns the resolved value; while the promise is pending it suspends the component, so the nearest <Suspense> boundary takes over. A rejected promise reaches the nearest error boundary, which is why use must never be wrapped in try/catch.

The rule that catches everybody: the promise must be the same object on every attempt. React 7,897 discards the state of a component that suspends before mounting and renders it from scratch, so a promise created during render is created anew each time and the component suspends forever.

Caching the promise so use can resolve itJavaScript
import { use, Suspense } from 'react';
const cache = new Map();
function getUser(id) {                       // one promise per id, reused across renders
  if (!cache.has(id)) {
    cache.set(id, fetch(`https://api.example.com/users/${id}`).then((r) => r.json()));
  }
  return cache.get(id);
}
function Profile({ id }) {
  const user = use(getUser(id));             // suspends only on the first attempt
  return <h2>{user.name}</h2>;
}
export default function App({ id }) {
  return <Suspense fallback={<p>Loading profile...</p>}><Profile id={id} /></Suspense>;
}

Reading context with use(ThemeContext) behaves like useContext but can be called conditionally. React 19.3 added a third resource: use(browser()), imported from react-dom, suspends during server rendering only, so a widget that needs window shows its fallback on the server and the real thing in a browser.