What Is the use
Hook?
The use
hook is a new React API that lets you read values from resources like Promises or contexts.
Its basic syntax is:
const value = use(resource);
Key Differences from Traditional Hooks
Unlike traditional React hooks (like useState
or useEffect
), the use
hook has some important differences:
Can be used in conditionals and loops: While regular hooks must be called at the top level of your component,
use
can be called insideif
statements, loops, and other conditional code.Multi-purpose functionality: It works with different types of resources (Promises and contexts).
Integrates with Suspense: When used with Promises, it automatically works with React's Suspense system.
Using use
with Context
When working with context, use
serves as a more flexible alternative to useContext
:
function Button() {
// This works even inside conditionals!
if (someCondition) {
const theme = use(ThemeContext);
return <button className={theme}>Click me</button>;
}
return <button>Default</button>;
}
The use
hook searches up the component tree just like useContext
to find the nearest context provider.
Using use
with Promises
The most powerful aspect of use
is its ability to work with Promises, especially in the context of Server Components:
function MessageComponent({ messagePromise }) {
// This unwraps the Promise value
const message = use(messagePromise);
return <p>{message}</p>;
}
When use
is called with a Promise:
The component "suspends" while the Promise is pending
When the Promise resolves, the component renders with the resolved value
If the Promise rejects, the nearest Error Boundary will catch the error
This is particularly useful in the Server Components pattern, where a Server Component fetches data and passes the Promise to a Client Component:
// Server Component
export default function App() {
const messagePromise = fetchMessage();
return (
<Suspense fallback={<p>Loading...</p>}>
<MessageComponent messagePromise={messagePromise} />
</Suspense>
);
}
// Client Component
("use client");
function MessageComponent({ messagePromise }) {
const message = use(messagePromise);
return <p>{message}</p>;
}
Error Handling with use
There are two main ways to handle errors when a Promise passed to use
rejects:
- Error Boundaries: Wrap the component in an Error Boundary to show a fallback UI when errors occur
<ErrorBoundary fallback={<p>Something went wrong</p>}>
<MessageComponent messagePromise={messagePromise} />
</ErrorBoundary>
- Promise.catch: Provide an alternative value if the Promise rejects
const safePromise = fetchData().catch(() => "Default value");
// Later in component
const data = use(safePromise); // Will be "Default value" if the Promise rejects
Important Limitations
You cannot call
use
in a try-catch blockuse
must be called inside a Component or Hook functionWhen passing Promises from Server to Client Components, the resolved value must be serializable
When to Use use
vs. Alternatives
Use
use(context)
instead ofuseContext
when you need conditional context accessIn Server Components, prefer
async/await
overuse
for data fetchingIn Client Components, prefer consuming Promises passed from Server Components with
use
rather than creating new Promises