React Server Components
Nicht "use client" hinklatschen — VERSTEHEN warum.
❌ Das große Missverständnis
"RSC ist Server-Side Rendering 2.0" — FALSCH.
SSR und RSC sind orthogonal. Sie lösen verschiedene Probleme und können zusammen ODER getrennt verwendet werden.
🧠 Das mentale Modell
SSR (Server-Side Rendering)
React → HTML → Browser
↓
Browser lädt ALLEN Code
↓
Hydration (Event Handlers anbringen)
❌ "Hydration Tax" — alles runterladen
RSC (Server Components)
Server Components → Serialisierter React-Baum
↓
Browser lädt nur Client Component Code
↓
Rekonstruiert React-Baum aus Stream
✅ Kein Code für Server Components im Bundle
Was RSC WIRKLICH ausgibt
RSC gibt kein HTML aus. Es gibt einen serialisierten React-Baum aus:
# RSC Wire Format
M1:{"id":"./ClientComponent.js","chunks":["client1"]}
J0:["$","@1",null,{"children":["$","span",null,{"children":"Hello"}]}]
M Zeilen = Module References (Client Components)
J Zeilen = React Element Trees
@1 = Referenz zu Client Component M1
Warum nicht einfach HTML? Mit dem RSC-Format kann React den Baum rekonstruieren — State bleibt erhalten, Updates sind minimal, es ist ein normales React-Update!
Die Bundler-Magie
Wenn ein Server Component ein Client Component importiert, passiert etwas Interessantes:
Was du schreibst:
import Button from './Button'
Was der Bundler macht:
{
$$typeof: Symbol(react.module.reference),
filename: "./Button.client.js",
name: "default"
} Nicht die Funktion — nur eine Referenz! Der Server kennt den Client-Code nicht, er weiß nur, dass es ihn gibt.
WARUM keine Hooks in Server Components?
useState
Wo soll der State leben? Server Components werden einmal ausgeführt und sind dann fertig. Es gibt keinen Browser, der State halten kann.
useEffect
Welchen DOM? Es gibt keinen! Effects laufen nach dem Rendern im Browser — Server Components rendern auf dem Server.
Das Design
Server Components sind stateless und effectless by design. Nicht als Einschränkung — als Feature!
Props müssen serialisierbar sein
❌ Das geht NICHT
// Server Component
function ServerPage() {
return (
<ClientButton
onClick={() => alert('hi')}
/>
)
} Funktionen sind nicht JSON-serialisierbar!
✅ Das geht
// Client Component
'use client'
function ClientButton() {
return (
<button
onClick={() => alert('hi')}
>Click</button>
)
} Event Handler leben im Client Component!
Aber: Client Components können Funktionen an andere Client Components übergeben. Die Einschränkung gilt nur an der Server→Client Grenze.
Das Composition Pattern
Client Components können keine Server Components importieren. Aber sie können Server Components als children erhalten!
// ServerPage.server.js
import ClientWrapper from './ClientWrapper'
import ServerContent from './ServerContent'
function ServerPage() {
return (
<ClientWrapper>
<ServerContent /> {/* ✅ Als children! */}
</ClientWrapper>
)
}
Der Trick: ServerContent wird vom Server gerendert, bevor es an den Client gesendet wird.
Der Client sieht nur den fertigen Output als props.
Suspense & Streaming
RSC unterstützt Streaming. Async Server Components können Suspense Boundaries haben:
Server startet Rendering, trifft auf async Component
Server sendet Placeholder (Suspense Fallback)
Client zeigt Fallback sofort an
Async Operation fertig → Server streamt fertigen Content
Client ersetzt Placeholder → Kein Flicker!
Wann was verwenden?
Server Component
- ✅ Data Fetching (DB, APIs)
- ✅ Große Dependencies (markdown parser, etc.)
- ✅ Sensitive Logik (API Keys, DB Queries)
- ✅ Statischer Content
Client Component
- ✅ Interaktivität (onClick, onChange)
- ✅ State (useState, useReducer)
- ✅ Effects (useEffect)
- ✅ Browser APIs (localStorage, etc.)
✅ Was ich WIRKLICH verstanden habe
- • RSC ≠ SSR — RSC produziert serialisierte React-Bäume, nicht HTML
- • Das Wire Format ist streambar und erlaubt progressive Updates
- • Keine Hooks weil Server Components stateless & effectless sind — by design
- • Module References — Bundler ersetzt Client Component Imports durch Referenzen
- • Props müssen serialisierbar sein an der Server→Client Grenze
- • Composition — Server Components als children übergeben, nicht importieren