use is a React API that lets you read the value of a resource like aPromise orcontext.
constvalue =use(resource);Reference
use(resource)
Calluse in your component to read the value of a resource like aPromise orcontext.
import{use}from'react';
functionMessageComponent({messagePromise}){
constmessage =use(messagePromise);
consttheme =use(ThemeContext);
// ...Unlike React Hooks,use can be called within loops and conditional statements likeif. Like React Hooks, the function that callsuse must be a Component or Hook.
When called with a Promise, theuse API integrates withSuspense andError Boundaries. The component callingusesuspends while the Promise passed touse is pending. If the component that callsuse is wrapped in a Suspense boundary, the fallback will be displayed. Once the Promise is resolved, the Suspense fallback is replaced by the rendered components using the data returned by theuse API. If the Promise passed touse is rejected, the fallback of the nearest Error Boundary will be displayed.
Parameters
resource: this is the source of the data you want to read a value from. A resource can be aPromise or acontext.
Returns
Theuse API returns the value that was read from the resource like the resolved value of aPromise orcontext.
Caveats
- The
useAPI must be called inside a Component or a Hook. - When fetching data in aServer Component, prefer
asyncandawaitoveruse.asyncandawaitpick up rendering from the point whereawaitwas invoked, whereasusere-renders the component after the data is resolved. - Prefer creating Promises inServer Components and passing them toClient Components over creating Promises in Client Components. Promises created in Client Components are recreated on every render. Promises passed from a Server Component to a Client Component are stable across re-renders.See this example.
Usage
Reading context withuse
When acontext is passed touse, it works similarly touseContext. WhileuseContext must be called at the top level of your component,use can be called inside conditionals likeif and loops likefor.use is preferred overuseContext because it is more flexible.
import{use}from'react';
functionButton(){
consttheme =use(ThemeContext);
// ...use returns thecontext value for thecontext you passed. To determine the context value, React searches the component tree and findsthe closest context provider above for that particular context.
To pass context to aButton, wrap it or one of its parent components into the corresponding context provider.
functionMyPage(){
return(
<ThemeContextvalue="dark">
<Form/>
</ThemeContext>
);
}
functionForm(){
// ... renders buttons inside ...
}It doesn’t matter how many layers of components there are between the provider and theButton. When aButtonanywhere inside ofForm callsuse(ThemeContext), it will receive"dark" as the value.
UnlikeuseContext,use can be called in conditionals and loops likeif.
functionHorizontalRule({show}){
if(show){
consttheme =use(ThemeContext);
return<hrclassName={theme}/>;
}
returnfalse;
}use is called from inside aif statement, allowing you to conditionally read values from a Context.
Pitfall
LikeuseContext,use(context) always looks for the closest context providerabove the component that calls it. It searches upwards anddoes not consider context providers in the component from which you’re callinguse(context).
import{createContext,use}from'react';constThemeContext =createContext(null);exportdefaultfunctionMyApp(){return(<ThemeContextvalue="dark"><Form/></ThemeContext>)}functionForm(){return(<Paneltitle="Welcome"><Buttonshow={true}>Sign up</Button><Buttonshow={false}>Log in</Button></Panel>);}functionPanel({title,children}){consttheme =use(ThemeContext);constclassName ='panel-' +theme;return(<sectionclassName={className}><h1>{title}</h1>{children}</section>)}functionButton({show,children}){if(show){consttheme =use(ThemeContext);constclassName ='button-' +theme;return(<buttonclassName={className}>{children}</button>);}returnfalse}
Streaming data from the server to the client
Data can be streamed from the server to the client by passing a Promise as a prop from aServer Component to aClient Component.
import{fetchMessage}from'./lib.js';
import{Message}from'./message.js';
exportdefaultfunctionApp(){
constmessagePromise =fetchMessage();
return(
<Suspensefallback={<p>waiting for message...</p>}>
<MessagemessagePromise={messagePromise}/>
</Suspense>
);
}TheClient Component then takesthe Promise it received as a prop and passes it to theuse API. This allows theClient Component to read the value fromthe Promise that was initially created by the Server Component.
// message.js
'use client';
import{use}from'react';
exportfunctionMessage({messagePromise}){
constmessageContent =use(messagePromise);
return<p>Here is the message:{messageContent}</p>;
}BecauseMessage is wrapped inSuspense, the fallback will be displayed until the Promise is resolved. When the Promise is resolved, the value will be read by theuse API and theMessage component will replace the Suspense fallback.
"use client";import{use,Suspense}from"react";functionMessage({messagePromise}){constmessageContent =use(messagePromise);return<p>Here is the message:{messageContent}</p>;}exportfunctionMessageContainer({messagePromise}){return(<Suspensefallback={<p>⌛Downloading message...</p>}><MessagemessagePromise={messagePromise}/></Suspense>);}
Note
When passing a Promise from a Server Component to a Client Component, its resolved value must be serializable to pass between server and client. Data types like functions aren’t serializable and cannot be the resolved value of such a Promise.
Deep Dive
A Promise can be passed from a Server Component to a Client Component and resolved in the Client Component with theuse API. You can also resolve the Promise in a Server Component withawait and pass the required data to the Client Component as a prop.
exportdefaultasyncfunctionApp(){
constmessageContent =awaitfetchMessage();
return<MessagemessageContent={messageContent}/>
}But usingawait in aServer Component will block its rendering until theawait statement is finished. Passing a Promise from a Server Component to a Client Component prevents the Promise from blocking the rendering of the Server Component.
Dealing with rejected Promises
In some cases a Promise passed touse could be rejected. You can handle rejected Promises by either:
- Displaying an error to users with an Error Boundary.
- Providing an alternative value with
Promise.catch
Pitfall
use cannot be called in a try-catch block. Instead of a try-catch blockwrap your component in an Error Boundary, orprovide an alternative value to use with the Promise’s.catch method.
Displaying an error to users with an Error Boundary
If you’d like to display an error to your users when a Promise is rejected, you can use anError Boundary. To use an Error Boundary, wrap the component where you are calling theuse API in an Error Boundary. If the Promise passed touse is rejected the fallback for the Error Boundary will be displayed.
"use client";import{use,Suspense}from"react";import{ErrorBoundary}from"react-error-boundary";exportfunctionMessageContainer({messagePromise}){return(<ErrorBoundaryfallback={<p>⚠️Something went wrong</p>}><Suspensefallback={<p>⌛Downloading message...</p>}><MessagemessagePromise={messagePromise}/></Suspense></ErrorBoundary>);}functionMessage({messagePromise}){constcontent =use(messagePromise);return<p>Here is the message:{content}</p>;}
Providing an alternative value withPromise.catch
If you’d like to provide an alternative value when the Promise passed touse is rejected you can use the Promise’scatch method.
import{Message}from'./message.js';
exportdefaultfunctionApp(){
constmessagePromise =newPromise((resolve,reject)=>{
reject();
}).catch(()=>{
return"no new message found.";
});
return(
<Suspensefallback={<p>waiting for message...</p>}>
<MessagemessagePromise={messagePromise}/>
</Suspense>
);
}To use the Promise’scatch method, callcatch on the Promise object.catch takes a single argument: a function that takes an error message as an argument. Whatever isreturned by the function passed tocatch will be used as the resolved value of the Promise.
Troubleshooting
“Suspense Exception: This is not a real error!”
You are either callinguse outside of a React Component or Hook function, or callinguse in a try–catch block. If you are callinguse inside a try–catch block, wrap your component in an Error Boundary, or call the Promise’scatch to catch the error and resolve the Promise with another value.See these examples.
If you are callinguse outside a React Component or Hook function, move theuse call to a React Component or Hook function.
functionMessageComponent({messagePromise}){
functiondownload(){
// ❌ the function calling `use` is not a Component or Hook
constmessage =use(messagePromise);
// ...Instead, calluse outside any component closures, where the function that callsuse is a Component or Hook.
functionMessageComponent({messagePromise}){
// ✅ `use` is being called from a component.
constmessage =use(messagePromise);
// ...