Start / Seminare / Next.js 16 Full-Stack-Entwicklung mit React und TypeScript
Modul
Formulare und Server Actions
6 Kapitel in diesem Modul-Video · Laufzeit
Transkript
Der gesprochene Text dieses Moduls zum Mitlesen, Überfliegen und Durchsuchen. Ein Klick auf einen Zeitstempel springt an die Stelle im Video.
Formulare und Server Actions
0:00 Bisher haben wir gelesen. Jetzt ändern wir Daten — und damit betreten wir den Bereich, in dem Fehler wehtun. Eine falsch angezeigte Belegung ist ärgerlich, eine falsch angelegte Buchung kostet Geld und Vertrauen. Die gute Nachricht: Der Weg dorthin ist in Next.js erstaunlich kurz geworden. Sie brauchen keinen eigenen Endpunkt, keinen Aufruf über das Netz, keine Serialisierung von Hand.
0:23 Die schlechte: Genau diese Kürze verleitet dazu, die Prüfungen wegzulassen, die weiterhin nötig sind. Wir bauen deshalb von Anfang an den vollständigen Ablauf — und Sie werden merken, dass er trotzdem übersichtlich bleibt.
Formulare in React 19
0:37 Fangen wir beim Formular an, und zwar bei einer Nachricht, die viele überrascht: Das Formular darf wieder ein Formular sein. Nach Jahren, in denen wir jedes Absenden abgefangen und selbst verarbeitet haben, geht React 19 einen Schritt zurück zum Ursprung — und gewinnt dabei etwas, das lange verloren war. Ein Formular bekommt eine Funktion zugewiesen, und React übernimmt den Rest: Absenden, Zurücksetzen, den Wartezustand.
1:02 Dazu kommen zwei Hooks — einer hält Ergebnis und Fehlermeldungen, der andere liefert den Absendestatus an eine tiefer liegende Schaltfläche, ohne dass Sie ihn durchreichen müssen. Was hier verschwindet, ist die Zeremonie: kein eigener Zustand für Laden, kein Abfangen des Absende-Ereignisses, kein manuelles Sammeln der Feldwerte.
1:21 Das Formular verhält sich wieder so, wie es im Web immer gedacht war — nur mit den Annehmlichkeiten von heute. Achten Sie darauf, was der Hook zurückgibt: das Ergebnis der letzten Ausführung, die Funktion für das Formular und einen Wartezustand. Diesen Wartezustand schreiben Sie nicht selbst und setzen ihn auch nicht zurück — er entsteht und vergeht von allein.
1:42 Worauf es ankommt: Der Wartezustand gehört an die Schaltfläche, nicht an die ganze Seite. Ein Formular, das beim Absenden komplett ausgraut, wirkt kaputter, als es ist. Ein Knopf, der kurz deaktiviert ist, verhindert Doppelklicks und sagt genau das Richtige aus. Das ist der Punkt, den ich für den unterschätztesten in diesem Modul halte.
2:03 Ein Formular in einer Server-Komponente sendet klassisch per Post — es funktioniert also, bevor auch nur ein Byte JavaScript geladen ist. Bei uns heißt das: Das Anmeldeformular des Portals arbeitet auf einer schlechten Mobilverbindung schon, während der Rest der Seite noch lädt. In Client- Komponenten werden Absendungen bis zur Hydration eingereiht und dann ausgeführt.
2:24 Fortschrittliche Verbesserung ist damit nicht mehr die Kür für besonders sorgfältige Teams, sondern der Normalfall — man muss sie nur nicht aktiv zerstören. Der zweite Punkt kostet beim ersten Mal zuverlässig zehn Minuten: Sobald Sie den Zustands-Hook verwenden, ändert sich die Signatur Ihrer Aktion. Der bisherige Zustand kommt als erstes Argument, die Formulardaten rutschen auf Platz zwei. Wer das übersieht, bekommt eine Fehlermeldung, die zunächst nach etwas anderem aussieht.
2:52 Der erste Punkt ist ein Vorgriff auf Modul vier, den Sie im Hinterkopf behalten sollten: Beide Hooks sind Client-Hooks. Ein Formular mit Zustandsanzeige ist also eine Client-Komponente — was völlig in Ordnung ist, solange die Grenze eng gezogen bleibt.
Server Actions schreiben
3:07 Jetzt zur Gegenseite: der Funktion, die die Änderung tatsächlich ausführt. Sie ist bemerkenswert unspektakulär — eine gewöhnliche asynchrone Funktion mit einer Zeile obendrauf. Was daran wichtig ist, steht nicht im Code, sondern in dem, was Sie beim Schreiben nicht vergessen dürfen. Deshalb gibt es dazu gleich einen festen Ablauf.
3:28 Eine Direktive macht aus einer Funktion etwas, das der Browser aufrufen kann, das aber ausschließlich auf dem Server läuft. Sie nimmt die Formulardaten entgegen, ändert die Daten und gibt ein schmales Ergebnis zurück. Kein eigener Endpunkt, keine Route, kein Aufruf im Client. Das ist beeindruckend bequem — und genau deshalb möchte ich früh einen Satz setzen, auf den wir noch zurückkommen: Diese Funktion ist über einen direkten Aufruf erreichbar, auch wenn sie nirgends verlinkt ist.
3:56 Bequem heißt hier nicht ungeschützt. Lesen Sie diese Aktion als Ablauf, nicht als Code: prüfen, ändern, invalidieren, schmal zurückgeben. Die vorletzte Zeile ist die, die in echten Projekten fehlt — das ist der Tag aus dem letzten Modul, ohne den die Belegungsübersicht den alten Stand zeigt. Und die letzte Zeile ist bewusst mager: Sie gibt zurück, dass es geklappt hat, nicht den angelegten Datensatz.
4:20 Worauf es ankommt: Diese Reihenfolge ist nicht Geschmack, sondern eine Checkliste. Wenn Sie sie einhalten, haben Sie die vier häufigsten Fehler dieses Modulbereichs bereits vermieden. Diese fünf Schritte gelten für jede einzelne Aktion, die Sie schreiben — ohne Ausnahme. Der rote Faden dahinter ist Misstrauen in der richtigen Reihenfolge: erst der Aufrufer, dann die Eingabe, dann die Änderung, dann die Folgen.
4:45 Schritt eins fällt am häufigsten weg, und zwar aus einem nachvollziehbaren Grund: Auf der Seite, die das Formular zeigt, wurde ja schon geprüft. Nur ist die Aktion ein eigener Eintrittspunkt — jemand kann sie aufrufen, ohne die Seite je gesehen zu haben. Wir vertiefen das in Modul elf. Der erste Punkt ist der wichtigste dieser Folie und überrascht fast jeden: Eine exportierte Aktion ist über einen direkten Aufruf erreichbar, auch wenn sie in keiner Oberfläche verlinkt ist.
5:14 Sie ist damit ein öffentlicher Endpunkt, nur ohne sichtbare Adresse. Der zweite Punkt ist eine praktische Eigenschaft, die man kennen sollte: Aktionen laufen nacheinander, nicht parallel. Wer damit mehrere Datenabfragen gleichzeitig anstoßen will, hat das falsche Werkzeug gewählt — dafür sind Server-Komponenten da, wie wir in Modul fünf gesehen haben.
Validierung an der Systemgrenze
5:34 Kommen wir zur Prüfung der Eingaben. Das Thema klingt nach Pflichtübung, und ich möchte es Ihnen anders verkaufen: Es geht um die Frage, wo in Ihrer Anwendung eigentlich die Grenze zwischen außen und innen verläuft. Alles, was von außen kommt, ist unbestätigte Behauptung — und Formulardaten sind dabei nur der offensichtlichste Fall.
5:53 Alles, was aus dem Browser kommt, lässt sich verändern: Formularfelder ebenso wie Suchparameter, Kopfzeilen und Pfadangaben. Ein Schema prüft diese Werte in der Aktion und liefert im Fehlerfall strukturierte Meldungen zurück, die das Formular direkt am betroffenen Feld anzeigen kann. Für alle, die aus dem React-Seminar kommen: Das Werkzeug kennen Sie dort als eigenes Thema. Hier interessiert nur diese eine Rolle — die Prüfung an der Systemgrenze.
6:19 Nicht die Schemasprache ist das Thema, sondern die Stelle, an der geprüft wird. Der wichtige Teil steht in der Mitte: die Prüfvariante, die nicht wirft, sondern ein Ergebnis liefert. Damit können Sie sauber entscheiden, ob es weitergeht oder ob Feldmeldungen zurück ans Formular gehen. Worauf es ankommt: Dieses Muster hat zwei Gewinner.
6:39 Der Nutzer bekommt eine Rückmeldung am richtigen Feld statt einer allgemeinen Fehlermeldung. Und Sie bekommen ab dieser Zeile typisierte, verlässliche Daten — alles danach arbeitet mit geprüften Werten. Das ist der Grund, warum diese Prüfung ganz vorn steht und nicht irgendwo dazwischen. Das ist keine theoretische Sorge. Die Attribute im Markup, die ein Pflichtfeld kennzeichnen, lassen sich in den Entwicklerwerkzeugen in fünf Sekunden entfernen — das ist keine Hackerkunst, das macht jeder neugierige Nutzer irgendwann versehentlich.
7:12 Und die Aktion ist ohnehin direkt aufrufbar, ganz ohne Formular. Deshalb die klare Aufgabenteilung: Die Prüfung im Browser ist Komfort, sie gibt schnelle Rückmeldung und spart Umläufe. Verbindlich ist allein die Prüfung, die sich nicht umgehen lässt. Beides zu haben ist richtig. Nur eines zu haben, ist es nicht. Der erste und zweite Punkt sind praktische Fallen: Formulardaten kommen als Zeichenketten, und ein leeres Feld kommt gar nicht als leerer Text an, sondern als nichts.
7:40 Wer das übersieht, bekommt Prüfmeldungen, die nicht zum Eingabefeld passen. Der dritte Punkt ist der konzeptionell wichtigste: Ein Schema prüft die Form, nicht die Fachlichkeit. Ob zwei Buchungen sich überschneiden, kann kein Schema wissen. Solche Regeln brauchen einen anderen Ort — und der beste davon ist die Datenbank selbst, wie wir in Modul neun sehen werden.
Fehler- und Erfolgszustände
8:02 Die Aktion ist gelaufen — und jetzt? Was zurückkommt, sieht der Browser, und zwar vollständig. Dieses Kapitel handelt von zwei Dingen: davon, wie der Nutzer erfährt, was passiert ist, und davon, was Sie dabei versehentlich mit herausgeben. Beides in einem, weil es dieselbe Zeile Code betrifft. Aus der Aktion kommt ein Zustandsobjekt zurück: Feldfehler, eine allgemeine Meldung oder schlicht der Erfolg.
8:27 Das Formular rendert daraus die Rückmeldung — ohne eigenen Zustand, ohne Effekt. Für Fehler, die nicht in der Aktion, sondern beim Rendern auftreten, greifen weiterhin die Fehlergrenzen aus Modul drei. Diese Trennung ist hilfreich: Fachliche Rückmeldungen laufen über den Zustand, technische Ausfälle über die Grenzen. Wer beides vermischt, bekommt eine Fehlerseite, weil ein Pflichtfeld leer war.
8:51 Der Unterschied zwischen diesen beiden Zeilen ist eine Datenschutzfrage. Oben wandert der komplette angelegte Datensatz in den Browser — mit allen Feldern, die die Datenbank zurückgibt, auch den internen. Unten wandert die Bestätigung und die Buchungsnummer. Für die Oberfläche macht das keinen Unterschied, sie zeigt ohnehin nur die Nummer an.
9:11 Worauf es ankommt: Das ist derselbe Gedanke wie bei den schmalen Eigenschaften aus Modul vier, nur in der Gegenrichtung. Rückgabewerte werden serialisiert und sind im Browser lesbar. Geben Sie zurück, was die Oberfläche braucht — und nichts weiter. Vier Wege, und die Reihenfolge in der letzten Zeile ist wichtig. Die Weiterleitung wirft intern eine Ausnahme, um den Ablauf abzubrechen — Code danach läuft nicht mehr.
9:36 Wenn Sie also erst weiterleiten und dann invalidieren wollten, passiert das Zweite nie. Der Nutzer landet auf der Zielseite und sieht dort alte Daten. Merken Sie sich die Reihenfolge: erst aufräumen, dann weiterleiten. Das ist einer der Fehler, die man genau einmal macht — er ist ärgerlich zu finden, weil beide Zeilen für sich richtig aussehen.
9:57 Der dritte Punkt beschreibt einen Fall, der in der Praxis mehr Schaden anrichtet als ein sichtbarer Fehler: Wenn in der Aktion etwas schiefgeht und nichts zurückkommt, bleibt das Formular stumm. Der Nutzer klickt, es passiert nichts, er klickt noch einmal. Bauen Sie also auch für den unerwarteten Fall eine Rückgabe. Der erste Punkt ist die Wiederholung, die es verdient: Ein zurückgegebener Datenbanksatz veröffentlicht interne Felder — jedes Mal, bei jedem Aufruf, ohne dass es jemandem auffällt.
Optimistische Oberflächen
10:25 Jetzt zu einem Muster, das gut aussieht und deshalb zu breit eingesetzt wird. Es geht darum, dem Nutzer das erwartete Ergebnis sofort zu zeigen, bevor der Server geantwortet hat. In Demos wirkt das großartig. In der Praxis hängt alles an einer Frage, die man vorher stellen muss — und die selten gestellt wird. React bietet dafür einen Hook, der den erwarteten Zustand sofort anzeigt und korrigiert, sobald die echte Antwort da ist.
10:51 Bei einer Merkliste ist das genau richtig: Der Stern wird sofort gelb, und im unwahrscheinlichen Fehlerfall geht er wieder aus — kein Drama. Bei einer verbindlichen Buchung ist es das nicht. Denn dort ist das Zurückrudern schlimmer als eine kurze Wartezeit. Jemand hat gelesen, dass sein Liegeplatz gebucht ist. Dass diese Meldung eine Sekunde später verschwindet, macht die Sache nicht besser, sondern schlechter.
11:15 Die Spalte rechts ist die eigentliche Entscheidungshilfe, und sie ist nicht technisch. Die Frage lautet nicht, ob das Muster funktioniert — das tut es immer. Sie lautet: Was kostet ein Rückzieher? Bei folgenlosen Vorgängen nichts, bei verbindlichen viel. Und je verbindlicher etwas ist, desto eher rechnet der Nutzer ohnehin mit einer kurzen Wartezeit — bei einer Zahlung würde ihn eine sofortige Bestätigung sogar misstrauisch machen.
11:41 Sie können sich also den Aufwand sparen und gewinnen dabei Glaubwürdigkeit. Der Grund steht im ersten Punkt: In der Demo schlägt nichts fehl. Man baut es ein, es fühlt sich schnell an, es geht in Produktion — und der Fehlerfall tritt erst nach Wochen auf, bei jemandem mit schlechter Verbindung. Dann springt die Oberfläche sichtbar zurück, und der Nutzer glaubt der Rücknahme nicht.
12:03 Das ist der Punkt, der mir wichtig ist: Wer gerade eine Bestätigung gesehen hat, hält die Korrektur für den Fehler, nicht die Bestätigung. Und eine ehrliche Wartezeit von dreihundert Millisekunden hat noch nie jemanden gestört. Der zweite Punkt ist der gefährlichste und hängt direkt am vorigen Kapitel: Ohne saubere Fehlerbehandlung bleibt der Nutzer im Glauben, es sei gespeichert.
12:24 Er schließt den Tab und kommt am nächsten Tag wieder — und die Buchung existiert nicht. Das ist kein Anzeigefehler mehr, das ist ein Vertrauensschaden. Der dritte Punkt betrifft eine Feinheit, die man erst im Betrieb bemerkt: Zwei schnell aufeinanderfolgende Änderungen können sich überholen, und die Reihenfolge der Antworten muss nicht der Reihenfolge der Klicks entsprechen.
Dateien hochladen
12:44 Zum Abschluss ein Thema, das technisch überraschend unspektakulär ist und betrieblich schnell heikel wird. Der Upload selbst läuft über dasselbe Formular und dieselbe Aktion, die wir schon kennen. Die Frage, die Sie beantworten müssen, ist eine ganz andere: Wo liegt die Datei danach eigentlich? Die Datei steckt in den Formulardaten, wie jedes andere Feld auch. Sie holen sie heraus und haben ein Dateiobjekt — mit Größe, Typ und Inhalt.
13:10 Zu prüfen sind drei Dinge, und alle drei auf dem Server: Ist die Datei zu groß, hat sie das erwartete Format, und darf diese Person überhaupt etwas hochladen? Bei uns im Portal laden Gäste ihre Bootspapiere hoch. Das ist ein guter Testfall, weil er alle drei Prüfungen braucht — und weil solche Dokumente personenbezogen sind.
13:31 Die beiden Prüfungen hier sind das Mindeste, und die zweite hat eine Einschränkung, die Sie kennen sollten: Der gemeldete Inhaltstyp kommt vom Browser. Er lässt sich fälschen. Für den ehrlichen Fehler — jemand lädt versehentlich ein Bild statt eines Dokuments hoch — reicht diese Prüfung völlig. Als Schutz gegen Absicht reicht sie nicht; dafür müssten Sie in den Inhalt schauen.
13:52 Worauf es ankommt: Prüfen Sie beides, Größe und Typ, und zwar bevor Sie irgendetwas mit der Datei tun. Eine abgelehnte Datei ist billiger als eine gespeicherte. Die ersten beiden Punkte sind derselbe Fehler in zwei Zeitstufen: Das Dateisystem des Servers ist kein Ablageort. Bei einer Instanz funktioniert es, bei zweien findet die andere die Datei nicht, und beim nächsten Deployment ist sie weg. Das ist der Klassiker, weil es lokal wunderbar läuft.
14:19 Der vierte Punkt ist eine Frage der Größenordnung: Große Dateien gehören nicht durch die Aktion, sondern direkt in einen Objektspeicher. Sonst wandert jedes Megabyte durch Ihren Anwendungsserver, der dafür nicht gedacht ist. Diese Aufgabe zieht alles zusammen, was wir heute besprochen haben — von der Eingabe bis zur Cache-Invalidierung.
14:39 Drei Dinge müssen am Ende stimmen: Die Buchung entsteht, Feldfehler erscheinen am richtigen Feld, und die Belegung zeigt den neuen Stand. Wer schneller ist, macht den Test, der mir am meisten am Herzen liegt: Rufen Sie Ihre Aktion mit einem direkten Aufruf auf, ohne Formular. Was dann passiert, sagt Ihnen mehr über die Sicherheit Ihrer Anwendung als jede Codeprüfung — und ist die perfekte Überleitung zu den nächsten Modulen.
Modul 7 zusammengefasst
15:03 Vier Sätze zum Mitnehmen. Formulare funktionieren ohne JavaScript, wenn man sie lässt. Jede Aktion prüft Anmeldung, Berechtigung und Eingaben selbst — die Seite schützt sie nicht. Zurückgegeben wird ein schmaler Zustand, nie ein Datensatz. Und optimistisch nur dort, wo ein Rückzieher wenig kostet. Im nächsten Modul sehen wir uns die Fälle an, in denen eine Aktion nicht reicht: wenn ein fremdes System anklopft, ein Zahlungsdienstleister etwa.
15:30 Dann brauchen Sie einen echten Endpunkt — und der bringt eigene Regeln mit.
Lieber mit Trainer? Dieses Modul ist Teil unserer Team-Schulungen — mit Übungen, Ihrem eigenen Code und Fragen, die ein Video nicht beantwortet. Mehr erfahren →