React Server Components erklärt: use client, Server Actions, Suspense | We.Inc
React Server Components verständlich erklärt: ein Grenzdiagramm, die Regeln für "use client", Datenladen, Server Actions für Formulare mit useActionState, Streaming mit Suspense und Lösungen für häufige Fehler.
React Server Components erklärt
React Server Components rendern auf dem Server und schicken fertige UI an den Browser, nicht ihr JavaScript. Sie können direkt auf Daten warten und Geheimnisse verwenden. Alles Interaktive kommt in eine Client Component, also eine Datei, die mit "use client" beginnt. Formulare können mit "use server" markierte Serverfunktionen aufrufen, und Suspense streamt langsame Teile später nach.
Die drei Direktiven und Hooks, die du brauchst
Schreibe
Bedeutet
(nichts)
Server Component, im Next.js App Router
"use client"
Diese Datei und ihre Importe laufen auch im Browser
"use server"
Diese exportierten Funktionen laufen beim Aufruf auf dem Server
<Suspense>
Zeige hier einen Fallback, solange dieser Teil lädt
Beginne mit dem Diagramm: Blaue Kästen bleiben auf dem Server, orangefarbene werden auch an den Browser ausgeliefert. Kopiere dann die Muster für Daten, Formulare und Streaming und nutze die Fehlertabelle, wenn sich der Build beschwert.
Lass Komponenten standardmäßig Server Components bleiben.
Lade Daten in async Server Components, nah an der Stelle, wo sie angezeigt werden.
Füge "use client" nur den kleinen Teilen hinzu, die State oder Handler brauchen.
Nutze Serverfunktionen für Formulare und Mutationen, mit useActionState für Rückmeldungen.
Umschließe langsame Teile mit Suspense oder füge eine loading.tsx hinzu, damit die Seite schnell erscheint.
Schiebe "use client" so weit wie möglich nach unten im Baum; eine Grenze nahe der Wurzel macht die ganze App wieder clientseitig.
Validiere jede Eingabe einer Serverfunktion. Sie ist ein öffentlicher Endpunkt, auch wenn nur dein Formular sie aufruft.
Prüfe in jeder Serverfunktion, wer der Nutzer ist, nicht nur auf der Seite, die das Formular anzeigt.
Übergib Server Components als children an Client Components, statt sie zu importieren.
Vermeide Anfrage-Wasserfälle: Starte unabhängige Fetches gemeinsam mit Promise.all.
Häufige Fragen
Sind Server Components dasselbe wie serverseitiges Rendering?
Nein. Serverseitiges Rendering macht beim ersten Laden aus jeder Komponente HTML und liefert trotzdem ihr JavaScript aus. Eine Server Component liefert ihr JavaScript nie aus, nur ihr Ergebnis. Client Components werden beim ersten Laden ebenfalls auf dem Server gerendert.
Brauche ich Next.js, um Server Components zu nutzen?
Sie brauchen ein Framework oder einen Bundler, der sie unterstützt. Der Next.js App Router ist am weitesten verbreitet; einige andere, etwa Waku, unterstützen sie ebenfalls.
Kann eine Client Component eine Server Component importieren?
Nein, ein Import aus einer Client-Datei zieht das Modul ins Client-Bundle. Übergib die Server Component stattdessen als children oder als andere Prop von einer übergeordneten Server Component.
Was ist der Unterschied zwischen Server Actions und Serverfunktionen?
React nennt inzwischen jede mit "use server" markierte Funktion eine Serverfunktion. Wird eine davon als Formular-Action verwendet oder innerhalb einer Transition aufgerufen, spricht man oft von einer Server Action. Next.js hat den Begriff Server Actions zuerst verwendet.
Funktioniert useActionState ohne JavaScript?
Das Formular sendet auch vor der Hydration an die Serverfunktion, es wird also abgeschickt. Der Pending-Zustand und die Inline-Meldung brauchen JavaScript, sorge also dafür, dass der Server in jedem Fall eine sinnvolle Seite zurückgibt.
Warum dieses Modell einer Website hilft
Der Großteil einer Marketing- oder Content-Seite ändert sich nach dem Rendern nie: Überschriften, Text, Bilder, Produktkarten. Als Server Components kosten sie überhaupt kein JavaScript, das lässt den Main Thread frei für die wenigen interaktiven Teile und verbessert meist Interaction to Next Paint.
Sicherheits-Checkliste für Serverfunktionen
Behandle jede "use server"-Funktion wie eine API-Route: Prüfe die Session, validiere die Eingabe mit einem Schema, prüfe, ob der Nutzer diesen Datensatz ändern darf, und gib nur zurück, was der Client braucht. Gib niemals Datenbankzeilen mit Feldern zurück, die der Nutzer nicht sehen soll.
Was wo läuft
Wo was laufen kann
Du musst
Server Component
Client Component
Eine Datenbank oder einen geheimen API-Schlüssel lesen
Ja
Nein (würde das Geheimnis offenlegen)
Direkt in der Komponente mit await auf Daten warten
Ja (async Komponente)
Nein
useState, useEffect, useReducer
Nein
Ja
onClick, onChange und andere Handler
Nein
Ja
window, localStorage, Browser-APIs
Nein
Ja, nach dem Mounten
Für die Komponente null JavaScript ausliefern
Ja
Nein
Die jeweils andere Art rendern
Ja, Client Components rendern
Nur Server Components, die als children oder Props übergeben werden
Server und Client Components
Eine Server Component, die Daten liest
Im App Router sind Komponenten Server Components, sofern nicht anders markiert. Sie können async sein und direkt mit der Datenbank sprechen; nichts von diesem Code erreicht den Browser.
Eine Client Component für Interaktion
"use client" ganz oben markiert eine Grenze: Diese Datei und alles, was sie importiert, wird für den Browser gebündelt. Halte diese Dateien klein und schiebe sie an die Blätter des Baums.
Eine Server Component durch eine Client Component reichen
Eine Client Component kann keine Server Component importieren, sie aber als children erhalten. Der Server rendert sie zuerst, und der Client platziert nur das Ergebnis.
Geheimnisse nicht versehentlich in den Browser bringen
Wenn du das Paket server-only importierst, schlägt der Build fehl, sobald eine Client-Datei dieses Modul importiert, so kann ein API-Schlüssel nicht durch einen unachtsamen Import durchsickern.
Serverfunktionen für Formulare
Ein Formular, das an eine Serverfunktion sendet
"use server" macht aus einer async Funktion einen Endpunkt, den das Formular aufrufen kann. Das Formular funktioniert schon, bevor JavaScript geladen ist, weil es ein echter Formular-Post ist.
Pending- und Ergebniszustand mit useActionState
useActionState (React 19) umschließt die Serverfunktion und liefert dir ihr letztes Ergebnis und ein Pending-Flag, so kann der Button Wird gesendet anzeigen und die Meldung ohne zusätzlichen State erscheinen.
Die Seitendaten nach einer Änderung aktualisieren
Teile Next.js nach einer Mutation mit, welche Daten eines Pfads veraltet sind, damit das nächste Rendern die Änderung zeigt.
Streaming mit Suspense
Den langsamen Teil mit Suspense streamen
Umschließe eine langsame Server Component mit Suspense. Der Rest der Seite wird sofort mit dem Fallback an dieser Stelle gesendet, und der langsame Teil wird nachgestreamt, sobald seine Daten eintreffen.
loading.tsx für eine ganze Route
Eine loading.tsx-Datei neben page.tsx umschließt diese Seite automatisch mit einer Suspense-Grenze, sodass die Navigation sie sofort anzeigt, während die Daten der Seite laden.
Anfragen gemeinsam starten
Wartest du in einer Server Component auf einen Fetch nach dem anderen, addieren sich ihre Zeiten. Starte sie gleichzeitig und warte dann auf beide.
Fehler, denen du begegnen wirst
Häufige Fehler und ihre Lösung
Was du siehst
Ursache
Lösung
Ein Hook wie useState funktioniert nur in einer Client Component
Ein Hook in einer Datei ohne "use client"
Verschiebe den interaktiven Teil in eine eigene Datei, die mit "use client" beginnt
Event-Handler können nicht an Props von Client Components übergeben werden
onClick wird von einer Server Component übergeben
Lege den Handler in die Client Component oder übergib stattdessen eine Serverfunktion
Funktionen können nicht direkt an Client Components übergeben werden
Eine normale Funktion wird als Prop über die Grenze gereicht
Markiere sie mit "use server", wenn sie auf dem Server laufen soll, oder definiere sie in der Client-Datei
Nur einfache Objekte können an Client Components übergeben werden
Klasseninstanzen wie Modelle voller Date-Objekte oder Maps werden als Props gesendet