What is it?
There are two places to fetch data: on the server (before the page renders) and on the client (after it loads). Server fetching gives fast first paint and good SEO. Client fetching gives interactivity — live updates, infinite scroll, optimistic UI. Modern apps use both, and knowing which fits which case is the skill.
Why it matters
Data fetching is where most performance and UX bugs live: waterfalls, loading spinners that never end, stale data after a mutation. Picking the right pattern — server component fetch vs TanStack Query vs server action — is an architecture decision reviewers probe hard.
What to learn
- Server-side fetching in RSC:
asynccomponents, nouseEffect - Why server fetching avoids client waterfalls and helps SEO
- Client-side fetching with TanStack Query: caching, refetch, mutations
- SWR as a lighter alternative
- Optimistic updates: update the UI before the server confirms
- Cache invalidation — the genuinely hard part
- Streaming + Suspense for progressive rendering
Common pitfall
Fetching in useEffect inside a Next.js App Router project. It creates
a client waterfall (render → effect → fetch → re-render) and a flash of
loading state. Server components fetch before render. Reach for client
fetching only when the data is interactive (user-triggered, live, or
paginated).
Resources
Primary (free):
- Next.js docs — Data fetching · docs
- TanStack Query docs · docs
- TkDodo — Practical React Query · article
Practice
Build a page that lists posts (server-fetched, fast first paint) with a "like" button on each (client mutation with optimistic update). Use a server component for the list and TanStack Query for the likes. Done when the list paints instantly and likes feel instant even on slow connections.
Outcomes
- Decide server vs client fetching for any piece of data.
- Set up TanStack Query with sensible cache defaults.
- Implement an optimistic update that rolls back on failure.
- Avoid client waterfalls in an App Router project.