--- title: use canary: true --- The `use` Hook is currently only available in React's Canary and experimental channels. Learn more about [React's release channels here](/community/versioning-policy#all-release-channels). `use` is a React Hook that lets you read the value of a resource like a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) or [context](/learn/passing-data-deeply-with-context). ```js const value = use(resource); ``` --- ## Reference {/*reference*/} ### `use(resource)` {/*use*/} Call `use` in your component to read the value of a resource like a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) or [context](/learn/passing-data-deeply-with-context). ```jsx import { use } from 'react'; function MessageComponent({ messagePromise }) { const message = use(messagePromise); const theme = use(ThemeContext); // ... ``` Unlike all other React Hooks, `use` can be called within loops and conditional statements like `if`. Like other React Hooks, the function that calls `use` must be a Component or Hook. When called with a Promise, the `use` Hook integrates with [`Suspense`](/reference/react/Suspense) and [error boundaries](/reference/react/Component#catching-rendering-errors-with-an-error-boundary). The component calling `use` *suspends* while the Promise passed to `use` is pending. If the component that calls `use` 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 the `use` Hook. If the Promise passed to `use` is rejected, the fallback of the nearest Error Boundary will be displayed. [See more examples below.](#usage) #### Parameters {/*parameters*/} * `resource`: this is the source of the data you want to read a value from. A resource can be a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) or a [context](/learn/passing-data-deeply-with-context). #### Returns {/*returns*/} The `use` Hook returns the value that was read from the resource like the resolved value of a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) or [context](/learn/passing-data-deeply-with-context). #### Caveats {/*caveats*/} * The `use` Hook must be called inside a Component or a Hook. * When fetching data in a [Server Component](/reference/react/use-server), prefer `async` and `await` over `use`. `async` and `await` pick up rendering from the point where `await` was invoked, whereas `use` re-renders the component after the data is resolved. * Prefer creating Promises in [Server Components](/reference/react/use-server) and passing them to [Client Components](/reference/react/use-client) 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](#streaming-data-from-server-to-client). --- ## Usage {/*usage*/} ### Reading context with `use` {/*reading-context-with-use*/} When a [context](/learn/passing-data-deeply-with-context) is passed to `use`, it works similarly to [`useContext`](/reference/react/useContext). While `useContext` must be called at the top level of your component, `use` can be called inside conditionals like `if` and loops like `for`. `use` is preferred over `useContext` because it is more flexible. ```js [[2, 4, "theme"], [1, 4, "ThemeContext"]] import { use } from 'react'; function Button() { const theme = use(ThemeContext); // ... ``` `use` returns the context value for the context you passed. To determine the context value, React searches the component tree and finds **the closest context provider above** for that particular context. To pass context to a `Button`, wrap it or one of its parent components into the corresponding context provider. ```js [[1, 3, "ThemeContext"], [2, 3, "\\"dark\\""], [1, 5, "ThemeContext"]] function MyPage() { return (
); } function Form() { // ... renders buttons inside ... } ``` It doesn't matter how many layers of components there are between the provider and the `Button`. When a `Button` *anywhere* inside of `Form` calls `use(ThemeContext)`, it will receive `"dark"` as the value. Unlike [`useContext`](/reference/react/useContext), `use` can be called in conditionals and loops like `if`. ```js [[1, 2, "if"], [2, 3, "use"]] function HorizontalRule({ show }) { if (show) { const theme = use(ThemeContext); return
; } return false; } ``` `use` is called from inside a `if` statement, allowing you to conditionally read values from a Context. Like `useContext`, `use(context)` always looks for the closest context provider *above* the component that calls it. It searches upwards and **does not** consider context providers in the component from which you're calling `use(context)`. ```js import { createContext, use } from 'react'; const ThemeContext = createContext(null); export default function MyApp() { return ( ) } function Form() { return ( ); } function Panel({ title, children }) { const theme = use(ThemeContext); const className = 'panel-' + theme; return (

{title}

{children}
) } function Button({ show, children }) { if (show) { const theme = use(ThemeContext); const className = 'button-' + theme; return ( ); } return false } ``` ```css .panel-light, .panel-dark { border: 1px solid black; border-radius: 4px; padding: 20px; } .panel-light { color: #222; background: #fff; } .panel-dark { color: #fff; background: rgb(23, 32, 42); } .button-light, .button-dark { border: 1px solid #777; padding: 5px; margin-right: 10px; margin-top: 10px; } .button-dark { background: #222; color: #fff; } .button-light { background: #fff; color: #222; } ``` ```json package.json hidden { "dependencies": { "react": "18.3.0-canary-9377e1010-20230712", "react-dom": "18.3.0-canary-9377e1010-20230712", "react-scripts": "^5.0.0" }, "main": "/index.js" } ```
### Streaming data from the server to the client {/*streaming-data-from-server-to-client*/} Data can be streamed from the server to the client by passing a Promise as a prop from a Server Component to a Client Component. ```js [[1, 4, "App"], [2, 2, "Message"], [3, 7, "Suspense"], [4, 8, "messagePromise", 30], [4, 5, "messagePromise"]] import { fetchMessage } from './lib.js'; import { Message } from './message.js'; export default function App() { const messagePromise = fetchMessage(); return ( waiting for message...

}>
); } ``` The Client Component then takes the Promise it received as a prop and passes it to the `use` Hook. This allows the Client Component to read the value from the Promise that was initially created by the Server Component. ```js [[2, 6, "Message"], [4, 6, "messagePromise"], [4, 7, "messagePromise"], [5, 7, "use"]] // message.js 'use client'; import { use } from 'react'; export function Message({ messagePromise }) { const messageContent = use(messagePromise); return

Here is the message: {messageContent}

; } ``` Because `Message` is wrapped in [`Suspense`](/reference/react/Suspense), the fallback will be displayed until the Promise is resolved. When the Promise is resolved, the value will be read by the `use` Hook and the `Message` component will replace the Suspense fallback. ```js src/message.js active "use client"; import { use, Suspense } from "react"; function Message({ messagePromise }) { const messageContent = use(messagePromise); return

Here is the message: {messageContent}

; } export function MessageContainer({ messagePromise }) { return ( ⌛Downloading message...

}>
); } ``` ```js src/App.js hidden import { useState } from "react"; import { MessageContainer } from "./message.js"; function fetchMessage() { return new Promise((resolve) => setTimeout(resolve, 1000, "⚛️")); } export default function App() { const [messagePromise, setMessagePromise] = useState(null); const [show, setShow] = useState(false); function download() { setMessagePromise(fetchMessage()); setShow(true); } if (show) { return ; } else { return ; } } ``` ```js src/index.js hidden // TODO: update to import from stable // react instead of canary once the `use` // Hook is in a stable release of React import React, { StrictMode } from 'react'; import { createRoot } from 'react-dom/client'; import './styles.css'; // TODO: update this example to use // the Codesandbox Server Component // demo environment once it is created import App from './App'; const root = createRoot(document.getElementById('root')); root.render( ); ``` ```json package.json hidden { "dependencies": { "react": "18.3.0-canary-9377e1010-20230712", "react-dom": "18.3.0-canary-9377e1010-20230712", "react-scripts": "^5.0.0" }, "main": "/index.js" } ```
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. #### Should I resolve a Promise in a Server or Client Component? {/*resolve-promise-in-server-or-client-component*/} A Promise can be passed from a Server Component to a Client Component and resolved in the Client Component with the `use` Hook. You can also resolve the Promise in a Server Component with `await` and pass the required data to the Client Component as a prop. ```js export default async function App() { const messageContent = await fetchMessage(); return } ``` But using `await` in a [Server Component](/reference/react/components#server-components) will block its rendering until the `await` 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 {/*dealing-with-rejected-promises*/} In some cases a Promise passed to `use` could be rejected. You can handle rejected Promises by either: 1. [Displaying an error to users with error boundary.](#displaying-an-error-to-users-with-error-boundary) 2. [Providing an alternative value with `Promise.catch`](#providing-an-alternative-value-with-promise-catch) `use` cannot be called in a try-catch block. Instead of a try-catch block [wrap your component in an Error Boundary](#displaying-an-error-to-users-with-error-boundary), or [provide an alternative value to use with the Promise's `.catch` method](#providing-an-alternative-value-with-promise-catch). #### Displaying an error to users with a error boundary {/*displaying-an-error-to-users-with-error-boundary*/} If you'd like to display an error to your users when a Promise is rejected, you can use an [error boundary](/reference/react/Component#catching-rendering-errors-with-an-error-boundary). To use an error boundary, wrap the component where you are calling the `use` Hook in an error boundary. If the Promise passed to `use` is rejected the fallback for the error boundary will be displayed. ```js src/message.js active "use client"; import { use, Suspense } from "react"; import { ErrorBoundary } from "react-error-boundary"; export function MessageContainer({ messagePromise }) { return ( ⚠️Something went wrong

}> ⌛Downloading message...

}>
); } function Message({ messagePromise }) { const content = use(messagePromise); return

Here is the message: {content}

; } ``` ```js src/App.js hidden import { useState } from "react"; import { MessageContainer } from "./message.js"; function fetchMessage() { return new Promise((resolve, reject) => setTimeout(reject, 1000)); } export default function App() { const [messagePromise, setMessagePromise] = useState(null); const [show, setShow] = useState(false); function download() { setMessagePromise(fetchMessage()); setShow(true); } if (show) { return ; } else { return ; } } ``` ```js src/index.js hidden // TODO: update to import from stable // react instead of canary once the `use` // Hook is in a stable release of React import React, { StrictMode } from 'react'; import { createRoot } from 'react-dom/client'; import './styles.css'; // TODO: update this example to use // the Codesandbox Server Component // demo environment once it is created import App from './App'; const root = createRoot(document.getElementById('root')); root.render( ); ``` ```json package.json hidden { "dependencies": { "react": "18.3.0-canary-9377e1010-20230712", "react-dom": "18.3.0-canary-9377e1010-20230712", "react-scripts": "^5.0.0", "react-error-boundary": "4.0.3" }, "main": "/index.js" } ```
#### Providing an alternative value with `Promise.catch` {/*providing-an-alternative-value-with-promise-catch*/} If you'd like to provide an alternative value when the Promise passed to `use` is rejected you can use the Promise's [`catch`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch) method. ```js [[1, 6, "catch"],[2, 7, "return"]] import { Message } from './message.js'; export default function App() { const messagePromise = new Promise((resolve, reject) => { reject(); }).catch(() => { return "no new message found."; }); return ( waiting for message...

}>
); } ``` To use the Promise's `catch` method, call `catch` on the Promise object. `catch` takes a single argument: a function that takes an error message as an argument. Whatever is returned by the function passed to `catch` will be used as the resolved value of the Promise. --- ## Troubleshooting {/*troubleshooting*/} ### "Suspense Exception: This is not a real error!" {/*suspense-exception-error*/} You are either calling `use` outside of a React component or Hook function, or calling `use` in a try–catch block. If you are calling `use` inside a try–catch block, wrap your component in an error boundary, or call the Promise's `catch` to catch the error and resolve the Promise with another value. [See these examples](#dealing-with-rejected-promises). If you are calling `use` outside a React component or Hook function, move the `use` call to a React component or Hook function. ```jsx function MessageComponent({messagePromise}) { function download() { // ❌ the function calling `use` is not a Component or Hook const message = use(messagePromise); // ... ``` Instead, call `use` outside any component closures, where the function that calls `use` is a component or Hook. ```jsx function MessageComponent({messagePromise}) { // ✅ `use` is being called from a component. const message = use(messagePromise); // ... ```