Skip to the solution
MediumFrontend5 min read

How do you fetch data in Next.js Client Components (SWR, React Query, use)?

907 views

The problem

Question presented to candidate: "Some data in our dashboard changes while the user is on the page and needs refetching. How do you fetch in a Client Component, and when would you do it on the client at all instead of on the server?"

What a strong answer should cover:

  • Prefer server fetching for the initial data; use the client for data that changes while the page is open, depends on client state, or is user-triggered.
  • Use a library: SWR or TanStack Query give caching, request deduplication, revalidation on focus, retries and mutations.
  • Avoid raw useEffect + fetch: it has race conditions, no cache, and double-fetches in Strict Mode development.
  • To stream server data into a client component, pass a Promise from a Server Component and read it with React use() inside Suspense.
  • Client-fetched data is not in the server HTML, so it does not help SEO or the first paint.

Clarifying questions expected:

  • "Does this data need to be in the first HTML?" β€” if so, fetch on the server.
  • "Does it change while the user is looking?" β€” that is where a client library earns its place.

Code / implementation expected: Yes β€” an SWR hook, and a server promise unwrapped with use().

  • nextjs
  • client-fetching
  • swr
  • react-query

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

5 min read Β· 8 sections

Read the code

An SWR hook and a server promise read with use()
// components/Notifications.tsx
"use client";
import useSWR from "swr";
const fetcher = (url: string) => fetch(url).then((r) => r.json());

export function Notifications() {
  const { data, error, isLoading } = useSWR("/api/notifications", fetcher, { refreshInterval: 30_000 });
  if (isLoading) return <p>Loading...</p>;
  if (error) return <p>Could not load notifications</p>;
  return <ul>{data.map((n: { id: string; text: string }) => <li key={n.id}>{n.text}</li>)}</ul>;
}

// app/page.tsx (Server Component) -> components/Stats.tsx ("use client")
//   <Suspense fallback={<p>Loading stats</p>}><Stats statsPromise={getStats()} /></Suspense>
//   inside Stats:  const stats = use(statsPromise);

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 41 of 129 in Next.js

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

All Next.js questions
Up nextMedium

What breaks when you upgrade to Next.js 16, and how do you migrate?

Continue