use() reads resources during render — promises and context. Think of it as a universal "unwrap" mechanism: give it a promise or a context object, and it returns the resolved value or the context value right inside your component function body.
Code:
1import { use, Suspense } from "react";23async function fetchUser(id: string) {4 const res = await fetch(`/api/users/${id}`);5 return res.json();6}78const userPromise = fetchUser("1");910function UserProfile() {11 const user = use(userPromise); // suspends until resolved12 return <h1>{user.name}</h1>;13}1415function App() {16 return (17 <Suspense fallback={<Loading />}>18 <UserProfile />19 </Suspense>20 );21}
Reading context:
1const ThemeContext = createContext("light");23function Button() {4 const theme = use(ThemeContext); // no useContext needed5 return <button className={theme}>Click</button>;6}
Conditional use:
1function UserProfile({ userId, showDetails }) {2 const user = use(userPromise);3 // use() can be called conditionally — unlike other hooks4 const details = showDetails ? use(detailsPromise) : null;5 return <div>...</div>;6}
How it works internally:
use(promise) is called and the promise is still pending, React suspends the component — it throws a special internal promise.<Suspense> boundary catches this and renders its fallback.use() now returns the resolved value.use(Context) is functionally equivalent to useContext(Context) but can be called conditionally.System design context:
cache() from React 19 or a library like SWR) so that the same promise is shared across components in one request.use(samePromise) share the same fetch instead of triggering two network requests.use() can await directly in Server Components, making data fetching linear and readable.Common pitfalls with root cause + fix:
useMemo.<Suspense>. Fix: Always provide a Suspense boundary — without one, React throws an error.use() for fire-and-forget side effects. Fix: use() is for reading values, not for triggering mutations.Benefits:
useEffect + useState danceuseContext in many cases with a unified APIMonitoring/observability: In production, track suspended component durations via React Profiler callbacks. Long suspensions indicate slow data sources that should be cached or pre-fetched.