Server Components
You can fetch data in Server Components using any asynchronous I/O.With the fetch API
Turn your component into an async function and await the fetch call:
Identical
fetch requests in a React component tree are memoized by default, so you can fetch data in the component that needs it without worrying about duplicate network requests. Fetch requests are not cached by default and will block the page from rendering. Use the use cache directive to cache results, or wrap the fetching component in <Suspense> to stream fresh data at request time.With an ORM or database
Since Server Components run on the server, credentials and query logic will never reach the client bundle. You can safely make database queries directly:Streaming
When data is slow, the whole route is blocked until all fetches complete. You can break the page into smaller chunks and progressively stream them to the client using React Suspense. There are two ways to add streaming:With loading.js
Create a loading.js file in the same folder as your page to stream the entire page while data is being fetched:
loading.js is nested inside layout.js and automatically wraps the page.js file in a <Suspense> boundary.
A layout that accesses uncached or runtime data (e.g.
cookies(), headers(), or uncached fetches) does not fall back to a same-segment loading.js. Instead, it blocks navigation until the layout finishes rendering. Wrap uncached access in its own <Suspense> boundary, or move the data fetching into page.js where loading.js covers it.With <Suspense>
<Suspense> gives you more granular control. You can immediately show page content that falls outside the boundary while streaming content inside it:
Client Components
There are two ways to fetch data in Client Components.Streaming data with the use API
Fetch data in a Server Component, pass the unawaited promise to your Client Component as a prop, and resolve it there with React’s use API:
use API to read the promise:
Community libraries
You can use community libraries like SWR or React Query to fetch data in Client Components. For example, with SWR:Examples
Sequential data fetching
Sequential fetching happens when one request depends on data from another. Use<Suspense> to stream in dependent data without blocking the entire page:
Parallel data fetching
Parallel fetching starts multiple requests at the same time. UsePromise.all to initiate requests in parallel and avoid waterfalls:
If one request fails when using
Promise.all, the entire operation fails. Use Promise.allSettled to handle partial failures instead.Sharing data with context and React.cache
You can share fetched data across both Server and Client Components by combining React.cache with context providers.
Create a cached data function:
use(), wrapped in <Suspense> for a fallback:
getUser() directly — because it’s wrapped with React.cache, multiple calls within the same request return the same memoized result:
React.cache is scoped to the current request only. Each request gets its own memoization scope — results are never shared between requests.