JS Guide
HomeQuestionsTopicsCompaniesResources
BookmarksSearch

Built for developers preparing for JavaScript, React & TypeScript interviews.

ResourcesQuestionsSupport
HomeQuestionsSearchProgress
HomeTopicsnextjsData Fetching
PrevNext
nextjs
intermediate
10 min read

Data Fetching

async
caching
data-fetching
nextjs
parallel
react-query
swr

In the App Router, Server Components are async functions that fetch data directly using fetch() or database queries — parallel fetching with Promise.all avoids waterfalls, request deduplication prevents redundant calls, and client-side fetching uses SWR or React Query for interactive data needs.

Key Points

1Async Server Components

Server Components are async functions that fetch data directly using fetch(), database queries, or file reads — no special API needed.

2Parallel Fetching

Use Promise.all to fetch data in parallel and avoid waterfall requests where each fetch waits for the previous one.

3Request Deduplication

React deduplicates identical fetch() calls during a single server render — multiple components can fetch the same URL without redundant requests.

4Client-Side Fetching

Client Components use SWR or React Query for real-time data, user interactions, and data that changes post-load — they cannot be async.

What You'll Learn

  • Fetch data in Server Components using async/await patterns
  • Avoid data fetching waterfalls with parallel fetching and Promise.all
  • Understand request deduplication and when to use React.cache()
  • Know when to use server-side vs client-side data fetching

Deep Dive

Data fetching in Next.js has fundamentally changed with the App Router. Instead of special functions (getStaticProps, getServerSideProps), Server Components fetch data directly as async functions.

Server Component Data Fetching

Server Components can be async and call fetch(), query databases, or read files directly:

TypeScript
async function UserProfile({ userId }: { userId: string }) {
  const user = await fetch(`https://api.example.com/users/${userId}`);
  const data = await user.json();
  return <h1>{data.name}</h1>;
}

No special API is needed — it's just an async function that returns JSX. This is simpler than the Pages Router's getStaticProps/getServerSideProps because data fetching lives inside the component that needs the data.

Parallel vs Sequential Fetching

Sequential fetching creates waterfalls — each request waits for the previous one:

JavaScript
// Sequential (waterfall) — bad
const user = await getUser(id);
const posts = await getPosts(id); // waits for getUser to finish

Use Promise.all for parallel fetching:

JavaScript
// Parallel — good
const [user, posts] = await Promise.all([getUser(id), getPosts(id)]);

Alternatively, start fetches at the page level and pass promises to child components, which await them individually. This pattern combined with Suspense enables streaming — each component resolves independently.

Request Deduplication

React automatically deduplicates identical fetch() calls during a single server render. If UserProfile and UserStats both call fetch('/api/users/1'), only one network request is made. This means you can fetch data where you need it without worrying about redundancy.

Deduplication only works with fetch() using the same URL and options. For non-fetch calls (direct database queries), use React's cache() function to deduplicate.

Fetch Cache Options

JavaScript
// Uncached — fresh on every request (Next.js 15+ default)
fetch(url);
 
// Cached indefinitely
fetch(url, { cache: 'force-cache' });
 
// Revalidate after 1 hour
fetch(url, { next: { revalidate: 3600 } });
 
// Tag for on-demand revalidation
fetch(url, { next: { tags: ['users'] } });

Non-fetch Data Sources

For databases, ORMs, or other non-fetch data sources, use unstable_cache (or the 'use cache' directive in Next.js 15+) to add caching:

TypeScript
import { unstable_cache } from 'next/cache';
 
const getCachedUser = unstable_cache(
  async (id: string) => db.users.findById(id),
  ['user'],
  { revalidate: 3600, tags: ['users'] }
);

Client-Side Fetching

Client Components cannot be async — they need client-side data fetching libraries:

  • SWR (by Vercel): Lightweight, stale-while-revalidate pattern, automatic revalidation on focus/reconnect
  • React Query (TanStack Query): More features — mutations, infinite queries, devtools, optimistic updates

Use client-side fetching for: real-time data, user-specific data after initial load, infinite scrolling, and data that changes based on user interaction.

Pages Router Legacy (getStaticProps/getServerSideProps)

The Pages Router used special exported functions:

  • getStaticProps — Fetch data at build time (SSG)
  • getServerSideProps — Fetch data per request (SSR)
  • getStaticPaths — Define dynamic routes for static generation

These still work in the pages/ directory but are not available in the App Router.

Key Interview Distinction

Server Components fetch data directly as async functions — no special APIs needed. Use Promise.all for parallel fetching to avoid waterfalls. React deduplicates identical fetch calls automatically. Client Components use SWR or React Query for interactive data needs. The Pages Router's getStaticProps/getServerSideProps are replaced by the simpler async component pattern.

Fun Fact

The async Server Component pattern was controversial when announced because React had always been synchronous. The React team had to rethink how components work at a fundamental level — a component that awaits a database query was an entirely new paradigm. This simplification eliminated the need for getStaticProps/getServerSideProps, which were the most confusing parts of the Pages Router for newcomers.

Learn These First

Next.js Fundamentals

beginner

Server & Client Components

intermediate

Continue Learning

Caching & Revalidation

advanced

Rendering Strategies

advanced

Practice What You Learned

How does data fetching work in Next.js?
mid
data-fetching
In the App Router, data is fetched directly in Server Components using `async/await` with opt-in caching via \"use cache\". The Pages Router uses special functions like `getStaticProps` (build time) and `getServerSideProps` (request time).
Previous
Server & Client Components
Next
Middleware
PrevNext