Push 'use client' to the Leaf
medium⏱ 20 minreactlesson
A product page where one like button dragged the whole module across the client boundary: the page section carries the client directive at its top, so the headline, tagline and price formatting all ship to the browser as JavaScript — and re-render on every like. The file simulates a Next.js App Router module graph: every 📁 file: banner is a module boundary, and the graders slice the file at those banners.
Your tasks:
- TODO(A) — Extract the interactive leaf: create a new pseudo-module
components/LikeButton.jsx holding the like state and the button, with "use client" at the top of that section — and nowhere else.
- TODO(B) — Make the page a real Server Component: strip the page section of the directive, the hooks and the handlers. Server Components render data to markup; they cannot hold state or attach events.
- TODO(C) — Compose across the boundary: the page renders
<LikeButton productId={…} initialLikes={…} /> — only serializable data crosses. Server Components can render Client Components; never the other way around.
The interview rule this drills: "use client" marks the root of a client bundle subtree — place it at the smallest leaf that needs interactivity, not at the page that happens to contain one.
Why this happens
"use client" doesn't mean "this file runs on the client" — it means "from this import edge down, everything becomes part of the client bundle". Put it on a page and the entire subtree pays: bigger bundles, hydration for markup that never changes, and re-renders of static content whenever the state ticks. Server Components invert the default: they run only on the server, may touch data directly, and emit HTML — but they cannot use state, effects or event handlers, because no live component instance exists in the browser. The composition rule follows from the module graph: a Server Component can render a Client Component (its props are serialized into the RSC payload), but a client module importing a server module converts it into client code. Hence the discipline this challenge drills: interactivity lives in small leaf client components; pages stay server-rendered and pass serializable props down.