Episode 2 — React Frontend Architecture NextJS / 2.21 — Working with Server Actions

2.21 — Quick Revision: Server Actions

<< 2.21 Overview


One Page Cheat Sheet

TopicRemember
Directive'use server' at top of module (or inline on a function)
vs Route HandlerAction = app-internal mutation ergonomics; Handler = HTTP API for any client
Form wiring<form action={fn}> — Server Components need no 'use client'
Extra argsfn.bind(null, id) — still verify ownership on server
Stateful formsuseActionState(action, initialState) — action gets (prev, formData)
Pending UIuseFormStatus() in child of <form>
Non-form callstartTransition(() => action(arg))
Fresh RSC datarevalidatePath / revalidateTag
Navigationredirect() / notFound() from server modules
SecuritySession + authz + Zod every time — no “trusted because React”

2.21.a — vs API routes (boundary)

  • Server Action: remote procedure for same app; great for forms and colocated mutations.
  • Route Handler: HTTP contract for arbitrary clients + webhooks.

2.21.b — use server (boundary)

  • Marks server graph; keeps secrets/server deps off client bundle.
  • Arguments/results must be serializable; think RPC hygiene.

2.21.c — Mutations & forms (UX)

  • Pair useActionState with Zod for inline errors.
  • Use useFormStatus for disabled submit buttons.
  • After writes, revalidatePath/revalidateTag to avoid stale RSC caches.

2.21.d — Security & production

  • Authn + authz + validation + rate limits on every mutation.
  • Safe client errors; rich logs only server-side.
  • CSRF posture: follow pinned Next guidance; defend high-risk flows explicitly.

Mental Diagram (30 seconds)

UI event → (form | transition) → Next runtime POST → 'use server' fn → DB → revalidate → UI

Phrases That Sound Senior

  • “I colocate mutations but share domain services with Route Handlers.”
  • “I treat actions like POST handlers: schema validate, authorize, rate limit.”
  • “I pick Route Handlers when I need a documented HTTP contract.”

Self-check: spoken answers

#PromptAnswer you should produce
1What is a Server Action?A server-only async function marked 'use server' invoked via Next’s runtime—great for same-app mutations without hand-written REST for every form.
2vs Route Handler?Handlers are public HTTP; actions are internal RPC-style calls tied to the Next app boundary.
3Why .bind for ids?Forms post FormData; bind injects trusted parameters while you still re-check authz server-side.
4Stale UI after mutation?Cached RSC tree—fix with revalidatePath/revalidateTag (and understand fetch tags).
5Client validation enough?Never—attackers can bypass; server Zod is the source of truth.
6Stripe webhooks?Route Handler verifying signatures—not a Server Action.
7Pending button state?useFormStatus in a child component under the <form>.
8Production errors?Structured failures for expected cases; generic message + server logs for unexpected.

<< 2.21 Overview