You can use await while rendering an async React Server Component. You cannot make a Client Component async and await in its render. In client-rendered code, use React’s use API to read a stable Promise under a <Suspense> boundary, or load data with a client-side pattern such as an Effect.
First, identify whether the component runs on the server or client
The key distinction is the component’s execution boundary, not just whether its function is written with async. Server Components run in the server or build environment. A component marked with 'use client' is a Client Component, where client-side hooks, event handlers, and browser APIs are available.
As an Amazon Associate I earn from qualifying purchases.
Server Components need to be enabled by the app’s framework or bundler; consult its current documentation and version requirements. The React use client documentation explains the client boundary and the APIs that require client execution.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsUse await in an async Server Component
An async Server Component can await the data it needs before returning its UI:
#1 Best Overall
async function Page({ id }) {
const note = await getNote(id);
return <article>{note.title}</article>;
}
React’s Server Components documentation explains that awaiting a Promise suspends that server rendering work until the Promise resolves. The component’s result is not ready until its awaited data is available.
Read a Promise in a Client Component with use
React does not support async components on the client. Instead, a Client Component can read a Promise passed to it by a Server Component using React’s use API:
'use client';
import { use } from 'react';
function Note({ notePromise }) {
const note = use(notePromise);
return <article>{note.title}</article>;
}
React documents this handoff from a Server Component to a Client Component, which reads the Promise with use. As React puts it, “Since async components are not supported on the client, we await the promise with use.” See React’s Server Components guide and the use reference.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Put a Suspense boundary around the reader
If the Promise is still pending, use suspends the component. A surrounding <Suspense> boundary can show a fallback until the content is ready:
Rank #3
<Suspense fallback={<p>Loading note…</p>}>
<Note notePromise={notePromise} />
</Suspense>
Suspense displays its fallback for work that suspends within its boundary; see the React Suspense reference for its behavior.
Keep the Promise stable across client renders
Do not create a new Promise by calling fetch directly in the expression passed to use, such as use(fetch('/api/data')). If that expression creates a fresh Promise on every render, React can warn about an uncached Promise. Use an architecture that supplies a stable or cached Promise instead. React’s use documentation describes this limitation.
Rank #4
Use an Effect for a client-side request after rendering
An Effect-based request keeps the component synchronous: it renders a loading state, starts the request after rendering, then updates state when the result arrives. For example:
function Profile({ userId }) {
const [profile, setProfile] = useState(null);
useEffect(() => {
let ignore = false;
fetchProfile(userId).then((result) => {
if (!ignore) setProfile(result);
});
return () => { ignore = true; };
}, [userId]);
if (profile === null) return <p>Loading…</p>;
return <h1>{profile.name}</h1>;
}
This example ignores a result after the effect is cleaned up, such as when the user ID changes. Production code should also handle request errors and use cancellation where appropriate.
Best Value
Effects are for synchronizing with external systems and do not run during server rendering. Fetching in an Effect does not activate Suspense by itself, so its loading UI comes from the component’s own state rather than a Suspense fallback. See the React useEffect reference.
Choose the pattern that matches the work
| Pattern | Where it runs | When content appears | Important consideration |
|---|---|---|---|
| Await in an async component | Server Component | The component’s server rendering work waits for the awaited Promise. | The app’s framework or bundler must support Server Components. |
Read a Promise with use |
Client Component | A Suspense boundary can show its fallback while the Promise is pending. | Supply a stable or cached Promise; handle suspended work with an appropriate boundary. |
| Fetch in an Effect | Client Component | The component first renders its loading state, then updates after the request resolves. | Effects do not run on the server and this approach does not activate Suspense. |
Framework and data-library support also affects where requests are created, how Promises are cached, and how data crosses the server/client boundary. Check those details in the documentation for your app’s stack; React’s cache reference documents a server-only cache API and its asynchronous rendering scope.
Quick Recap
Common mistakes to avoid
- Making a Client Component async: async component rendering is supported on the server, not the client.
- Passing a newly created Promise to
useon every render: this can cause an uncached-Promise warning. - Expecting Suspense to catch a request started in
useEffect: Effect-based fetching does not activate Suspense by itself. - Treating
useEffectas server render-timeawait: Effects run after client rendering and do not run on the server.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




