Server Components, Actions and SSR
Server Components run only on the server and ship no JavaScript; Client Components are server-rendered and then hydrated. Know where the boundary is, what can cross it, and that every Server Action is a public endpoint.
Key points
- 1
'use client'marks a module as a client entry point: everything it imports joins the client module graph. It does not mean "render only in the browser", since Client Components are still server-rendered for the first load. - 2
Compose by passing Server Components as
childrenor props into Client Components; importing a Server Component into a client module turns it into client code. - 3
Props crossing the boundary must be serializable: primitives, plain objects and arrays, Date, Map, Set, typed arrays, Promises, JSX and Server Functions. Class instances and plain functions are not.
- 4
Server Actions (
'use server') are POST endpoints. Validate input, authenticate and authorize inside every action, and return only what the UI needs. - 5
useActionState(action, initial)callsaction(prevState, formData)and returns[state, formAction, isPending].useFormStatusreads its parent form only.useOptimisticreverts when the action settles. - 6
Avoid waterfalls with
Promise.all; stream slow parts by passing un-awaited promises to components under Suspense boundaries. - 7
React
cache()dedupes within one request (define it at module level); persistent caching across requests is a framework feature (Cache Components in Next.js 16).
Common traps
redirect()throws to navigate, so code after it never runs and a surrounding try/catch swallows it.Module-level variables in server code are shared by all concurrent requests and leak data between users.
Calling a helper exported from a
'use client'module inside a Server Component throws, because on the server it is only a client reference.
Read the source
Test yourself on Server Components, Actions and SSR
Ten questions, with the answer and explanation after each one.