patternjavascriptreactTip
use() hook for reading promises and context in React 19
Viewed 0 times
React 19
use hookreact 19promiseSuspensecontextasync renderinguse()
Problem
Before React 19, reading a promise inside a component required either useEffect (causing a waterfall) or a data fetching library. Reading context required useContext at the top level of a component — it couldn't be called inside conditions or loops.
Solution
Use the use() hook to read promises (with Suspense) and context anywhere in a component:
import { use, Suspense, createContext } from 'react';
// Read a promise — component suspends until resolved
function UserCard({ userPromise }) {
const user = use(userPromise); // suspends here
return <div>{user.name}</div>;
}
<Suspense fallback={<Skeleton />}>
<UserCard userPromise={fetchUser(id)} />
</Suspense>
// Read context conditionally (not possible with useContext)
function Toolbar({ showTheme }) {
if (showTheme) {
const theme = use(ThemeContext); // conditional — allowed with use()
return <div className={theme}>...</div>;
}
return null;
}
// Server Component passing a promise to a Client Component
async function Page() {
const dataPromise = fetchData(); // starts fetching but doesn't await
return (
<Suspense fallback={<Loading />}>
<ClientComponent dataPromise={dataPromise} />
</Suspense>
);
}
import { use, Suspense, createContext } from 'react';
// Read a promise — component suspends until resolved
function UserCard({ userPromise }) {
const user = use(userPromise); // suspends here
return <div>{user.name}</div>;
}
<Suspense fallback={<Skeleton />}>
<UserCard userPromise={fetchUser(id)} />
</Suspense>
// Read context conditionally (not possible with useContext)
function Toolbar({ showTheme }) {
if (showTheme) {
const theme = use(ThemeContext); // conditional — allowed with use()
return <div className={theme}>...</div>;
}
return null;
}
// Server Component passing a promise to a Client Component
async function Page() {
const dataPromise = fetchData(); // starts fetching but doesn't await
return (
<Suspense fallback={<Loading />}>
<ClientComponent dataPromise={dataPromise} />
</Suspense>
);
}
Why
use() is not a Hook — it can be called inside conditions, loops, and after early returns. For promises, React integrates with Suspense to show fallback UI during loading and with Error Boundaries for rejection. For context, it's a more flexible alternative to useContext.
Gotchas
- use(promise) re-suspends on every render if you pass a new promise object — cache the promise outside the component
- use() cannot be used in event handlers — only in component render or other hooks
- Rejected promises propagate to the nearest Error Boundary — always have one
- use(Context) and useContext(Context) are equivalent when called at the top level
Code Snippets
Stable promise reference for use()
// Cache promise outside component to avoid infinite suspend
const userPromise = fetchUser(123); // created once
function Profile() {
const user = use(userPromise);
return <h1>{user.name}</h1>;
}Context
When building with React 19 and needing to read async data or context in a flexible way
Revisions (0)
No revisions yet.