Start / Seminare / React v19 Grundlagen & Moderne Features
Modul
React v19 - TanStack Query v5
5 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.
React v19+ — TanStack Query v5
0:00 Es gibt eine Einsicht, die viele Projekte teuer bezahlt haben, bevor sie sie hatten: Daten vom Server sind kein normaler Zustand. Ein Schalter, den ein Nutzer umlegt, gehört Ihrer Anwendung — Sie wissen jederzeit, wie er steht. Eine Liste von Bestellungen gehört Ihnen nicht. Sie liegt woanders, jemand anderes ändert sie, und Ihre Kopie wird schlecht, während sie auf dem Bildschirm steht.
0:22 Wer solche Daten wie einen Schalter behandelt, baut jedes Mal dieselben drei Probleme nach. Der Satz auf der Folie fasst die Alternative zusammen: Solche Daten will man nicht verwalten, man will sie zwischenspeichern.
Server-State mit TanStack Query
0:35 Der rote Faden führt von der ersten Abfrage bis zu einer getesteten Datenschicht, die auch beim Rendern auf dem Server funktioniert. Auf dem Weg dorthin klären wir die Fragen, an denen es im Alltag hakt: Wann gelten Daten als veraltet? Wie hält man den Zwischenspeicher nach einer Änderung sauber? Und wie blättert man durch eine Liste, ohne dass die Seite bei jedem Klick weiß aufblitzt? Das sind Kleinigkeiten mit großer Wirkung auf den Eindruck von Qualität.
1:02 Die zweite Frage ist die interessante, denn sie berührt drei Probleme, die praktisch jedes Projekt einmal von Hand gelöst hat — meist schlechter als nötig. Zwischenspeichern klingt einfach, bis man sich fragt, wann man neu lädt. Nach einer Änderung die richtigen Listen zu aktualisieren, klingt trivial, bis man vier Ansichten hat, die dieselben Daten zeigen.
1:21 Und die sofortige Rückmeldung vor der Serverantwort ist verführerisch, bis man den Rückweg im Fehlerfall braucht. Wenn Sie da Geschichten haben, immer her damit.
Grundlagen & Mentales Modell
1:31 Beginnen wir mit dem Denkmodell, denn hier entscheidet sich, ob dieses Werkzeug für Sie einleuchtend oder verwirrend ist. Wer die Unterscheidung zwischen den beiden Arten von Zustand verinnerlicht hat, versteht danach fast alles von selbst. Nehmen Sie sich für dieses Kapitel Zeit — es ist weniger technisch als der Rest und trotzdem das wichtigste.
1:50 Ein Bild hilft hier: Denken Sie an den Unterschied zwischen Ihren Notizen und einem Fahrplan an der Haltestelle. Ihre Notizen gehören Ihnen, sie ändern sich nur, wenn Sie etwas schreiben. Der Fahrplan hängt woanders, jemand anderes aktualisiert ihn, und Ihre abfotografierte Kopie ist irgendwann falsch — ohne dass Sie es merken. Genau darum geht es.
2:11 Server-Daten sind eine Kopie von etwas, das anderswo lebt. Die richtige Frage ist deshalb nicht "wie speichere ich sie", sondern "wann hole ich sie wieder". Der dritte Punkt ist wichtiger, als er wirkt, weil er ein verbreitetes Missverständnis ausräumt. Dieses Werkzeug ersetzt keine Zustandsverwaltung für die Oberfläche — ob eine Seitenleiste offen ist oder welcher Reiter aktiv ist, bleibt Aufgabe Ihres bisherigen Ansatzes.
2:36 Was es ersetzt, ist der Teil davon, der sich mit Serverdaten beschäftigt. Und der macht in vielen Projekten achtzig Prozent des Aufwands aus. Nach der Umstellung sind die verbleibenden Zustandsverwaltungen oft überraschend klein. Der dritte Schritt ist eine Empfehlung, die ich nachdrücklich ausspreche. Das mitgelieferte Entwicklungswerkzeug zeigt Ihnen live, welche Abfragen existieren, welchen Zustand sie haben und wann neu geladen wird.
3:02 Das ist bei diesem Thema mehr als Komfort: Der ganze Zwischenspeicher ist sonst unsichtbar, und man diskutiert über Vermutungen. Mit diesem Fenster sehen Sie zu, wie eine Abfrage veraltet und beim nächsten Fensterwechsel neu lädt. Ein Nachmittag damit ersetzt eine Menge Erklärung. Zwei Angaben genügen: eine Bezeichnung und eine Funktion, die Daten holt. Alles andere ergibt sich.
3:24 Der wichtigste Punkt steht in der Fußzeile: Die Funktion muss im Fehlerfall werfen, nicht etwa einen Fehlerwert zurückgeben. Nur dann kann der Fehlerzustand gefüllt werden. Wer aus der Welt der eigenen Datenlade-Funktionen kommt, hat sich oft angewöhnt, Fehler als Rückgabewert zu behandeln — hier ist das genau falsch herum und führt dazu, dass ein Fehlertext als vermeintlich gültige Daten in der Oberfläche landet.
3:49 Binden Sie eine erste Abfrage an und bilden Sie alle drei Zustände ab. Öffnen Sie dabei unbedingt das Entwicklungswerkzeug und lassen Sie es offen. Wechseln Sie dann in ein anderes Fenster und wieder zurück — Sie werden sehen, dass automatisch neu geladen wird. Dieses Verhalten ist voreingestellt und überrascht viele beim ersten Mal.
4:08 Es ist der sichtbarste Beleg dafür, dass hier jemand die Frage "wann sind meine Daten veraltet" ernst nimmt. Der erste Punkt ist der häufigste Fehler bei einer Umstellung: Man holt die Daten über die Abfrage und schreibt sie dann trotzdem noch in eine eigene Zustandsvariable — aus Gewohnheit. Damit haben Sie zwei Wahrheiten, die auseinanderlaufen, sobald im Hintergrund neu geladen wird. Der Zwischenspeicher ist Ihr Zustand, es braucht keine Kopie.
4:34 Der zweite Punkt ist die Fehlerbehandlung von eben, und der letzte ist ein Einrichtungsfehler mit klarer Fehlermeldung — der immerhin löst sich schnell.
Caching & Query Keys verstehen
4:43 Jetzt zum Herzstück. Zwei Dinge muss man wirklich verstanden haben: was der Schlüssel einer Abfrage bedeutet und was die beiden Zeitangaben steuern. Genau diese drei Begriffe werden am häufigsten verwechselt — und die Verwechslung erklärt fast jedes seltsame Verhalten. Wenn Sie später einmal ratlos vor Ihrem Zwischenspeicher stehen, liegt die Antwort mit hoher Wahrscheinlichkeit in diesen Folien.
5:05 Der Schlüssel ist der beste Vergleich zu etwas, das Sie schon kennen: Er ist die Abhängigkeitsliste eines Effekts. Ändert sich etwas darin, gilt das als andere Abfrage und wird neu geholt. Daraus folgt die praktische Regel: Alles, was das Ergebnis beeinflusst, gehört in den Schlüssel — der Filter, die Seitennummer, die Kennung des Datensatzes.
5:26 Der Lebenszyklus daneben klingt kompliziert und ist einfach: frisch, veraltet, unbenutzt, weggeräumt. Nur zwei dieser Übergänge steuern Sie selbst. Zum ersten Punkt die Klärung, die den größten Unterschied macht. Die eine Zeitangabe bestimmt, wie lange Daten als frisch gelten — solange wird gar nicht neu geladen. Die andere bestimmt, wie lange unbenutzte Daten im Speicher bleiben, bevor sie weggeräumt werden. Die erste beeinflusst Netzverkehr, die zweite Arbeitsspeicher.
5:55 Die Voreinstellung ist übrigens null für die erste — Daten gelten sofort als veraltet. Das ist ein bewusst vorsichtiger Standard und für Daten, die sich selten ändern, oft zu vorsichtig. Der vierte Schritt ist die wichtigste organisatorische Empfehlung des Tages. Schlüssel als Zeichenketten direkt in Komponenten zu schreiben, funktioniert genau so lange, bis Sie an drei Stellen dieselbe Liste laden und an einer davon das Ungültigmachen vergessen — weil die Schreibweise minimal abweicht.
6:23 Eine zentrale Stelle, an der alle Schlüssel definiert werden, macht daraus einen Compiler-Fehler statt einer stillen Fehlfunktion. Zehn Zeilen Aufwand, die man nie bereut. Was Sie hier sehen, ist mehr als Ordnung. Der Schlüssel und die Ladefunktion gehören zusammen, denn sie beschreiben dieselbe Sache — es ergibt keinen Sinn, sie an verschiedenen Orten zu pflegen.
6:44 Beachten Sie außerdem den Aufbau des Schlüssels: Er beginnt mit der allgemeinen Bezeichnung und wird nach hinten spezifischer. Das ist Absicht, denn das Ungültigmachen arbeitet mit Präfixen. Sie können damit später alle Listen auf einmal treffen, unabhängig vom Filter — oder gezielt nur eine. In dieser Übung bauen Sie das Muster, das Sie in fast jedem Projekt brauchen: eine Liste und eine Detailansicht, die sich denselben Zwischenspeicher teilen.
7:10 Achten Sie auf den Moment, in dem Sie von der Liste ins Detail wechseln — mit richtig gesetzten Schlüsseln sind die Daten oft schon da. Für die Zusatzaufgabe mit der abhängigen Abfrage: Der Schalter zum Aktivieren ist die Antwort auf die Frage, was passiert, wenn noch gar nichts ausgewählt ist. Der erste Punkt hat ein Symptom, das man einmal erlebt haben muss: Sie wechseln den Filter, und es erscheinen die Daten des alten Filters — weil aus Sicht des Zwischenspeichers gar nichts passiert ist.
7:37 Der Schlüssel war ja derselbe. Der letzte Punkt ist die Verwechslung der beiden Zeitangaben, über die wir gesprochen haben; sie führt regelmäßig zu der Frage, warum ständig neu geladen wird, obwohl doch eine hohe Zeit eingestellt ist — nur eben die falsche.
Mutations & Cache-Updates
7:51 Bisher haben wir nur gelesen. Jetzt wird geschrieben — und damit stellt sich die eigentlich interessante Frage: Was passiert nach einer Änderung mit all den Ansichten, die die alten Daten zeigen? Dafür gibt es zwei Wege, und sie unterscheiden sich in Aufwand und Sicherheit. Und wir schauen uns die Technik an, mit der eine Oberfläche schneller wirkt, als das Netz erlaubt.
8:13 Die Empfehlung in der Notiz ist eindeutig und ich unterstreiche sie: Als Standard erklären Sie die betroffenen Daten für veraltet, statt den Zwischenspeicher von Hand zu füllen. Der Grund ist Verlässlichkeit. Wenn Sie die Antwort des Servers direkt einsetzen, gehen Sie davon aus, genau zu wissen, was der Server getan hat. Meistens stimmt das.
8:32 Aber wenn er nebenbei einen Zeitstempel setzt oder eine Nummer vergibt, hat Ihre Kopie das nicht. Ein Nachladen kostet eine Anfrage und ist immer richtig. Der letzte Punkt beschreibt die Königsdisziplin und verdient eine Einordnung. Bei einem optimistischen Update zeigen Sie die Änderung sofort an, bevor der Server geantwortet hat.
8:52 Das fühlt sich unmittelbar an — genau der Unterschied zwischen einer Anwendung, die reagiert, und einer, die man bedient und dann wartet. Der Preis ist ein sauberer Rückweg: Wenn der Server ablehnt, muss der alte Zustand zurück. Wer diesen Rückweg vergisst, hat eine Anwendung, die Dinge anzeigt, die es nicht gibt. Zum zweiten Punkt eine Klarstellung, die häufig Verwirrung stiftet: Es gibt zwei Arten, eine Änderung auszulösen.
9:18 Die eine ist ein Anstoßen ohne Rückmeldung — sie gibt kein Versprechen zurück, und darauf zu warten funktioniert nicht. Die andere gibt eines zurück und lässt sich abwarten. Wer im Absendevorgang eines Formulars danach noch etwas tun will, braucht die zweite. Die erste ist für den einfachen Fall gedacht, in dem alles Weitere in den Rückrufen passiert.
9:39 Der Standardfall in fünf Zeilen. Interessant ist die Feinheit im Ungültigmachen: Es wirkt über Präfixe. Der angegebene Schlüssel trifft also auch alle Abfragen, deren Schlüssel damit beginnt — sämtliche Filtervarianten der Liste auf einmal. Das ist meist genau, was man will, und gelegentlich zu viel. Wenn Sie merken, dass nach einer kleinen Änderung ein Dutzend Abfragen neu laden, ist das der Hebel: spezifischer werden, nicht das Ungültigmachen weglassen.
10:07 Hier bauen Sie den optimistischen Weg mit Rückweg. Testen Sie ihn unbedingt ehrlich: Lassen Sie den Server absichtlich ablehnen und schauen Sie zu, ob die Oberfläche sauber zurückspringt. Das ist der halbe Aufwand dieser Technik, und genau der wird gern übersprungen, weil im Erfolgsfall ja alles gut aussieht. Die Zusatzaufgabe zeigt eine leichtere Variante, die für einfache Fälle oft völlig genügt und deutlich weniger Code braucht.
10:31 Der zweite Punkt ist das Ergebnis eines vergessenen Rückwegs, und das Symptom ist tückisch: Der Eintrag steht in der Liste, verschwindet aber nach dem nächsten Neuladen. Der Nutzer glaubt, er habe etwas gespeichert, das nie ankam. Der dritte Punkt ist das Gegenteil und der häufigere Anfängerfehler: Man macht sicherheits- halber alles ungültig, und ein Klick löst zwanzig Abfragen aus.
10:54 Beides sind Fragen der richtigen Dosis, nicht der richtigen Technik.
Fortgeschrittene Patterns
10:58 Jetzt zu den Mustern, die aus einer funktionierenden Anwendung eine angenehme machen. Blättern ohne Flackern, Daten, die schon da sind, bevor man klickt, und eine saubere Einbindung in die Lade- und Fehlerbehandlung von React. Es sind alles Kleinigkeiten — aber genau diese Kleinigkeiten unterscheiden eine Anwendung, die man gern benutzt, von einer, die man benutzen muss.
11:20 Das erste Muster ist mein Lieblingsbeispiel für den Unterschied zwischen funktioniert und ist gut. Standardmäßig gilt beim Blättern: neue Seitennummer, anderer Schlüssel, also andere Abfrage — und die hat noch keine Daten. Die Folge ist ein weißes Aufblitzen bei jedem Klick. Mit der Einstellung für Platzhalterdaten bleibt die alte Seite sichtbar, bis die neue da ist.
11:42 Der technische Aufwand ist eine Zeile, der Unterschied im Empfinden ist der zwischen einer Tabelle, die ruckelt, und einer, die trägt. Der dritte Punkt verdient eine praktische Erklärung. Mit der Auswahl-Funktion können Sie aus den geladenen Daten nur den Teil herausgreifen, den eine bestimmte Komponente braucht — etwa nur die Anzahl statt der ganzen Liste.
12:02 Der Effekt: Diese Komponente zeichnet nur neu, wenn sich die Anzahl ändert, nicht bei jeder Änderung an irgendeinem Eintrag. Das ist die feinkörnige Variante dessen, was wir sonst über Anmeldungen auf schmale Ausschnitte sagen. Der dritte Punkt ist einer der besten Kosten-Nutzen-Hebel überhaupt. Wenn jemand mit der Maus über einen Listeneintrag fährt, ist die Wahrscheinlichkeit hoch, dass er gleich klickt — und in diesen zweihundert Millisekunden lassen sich die Detaildaten bereits holen.
12:30 Beim Klick ist dann alles da. Der Nutzer erlebt eine Anwendung ohne Ladezeit, obwohl die Daten dieselbe Zeit gebraucht haben. Man hat sie nur an eine Stelle verlegt, an der niemand wartet. Eine Zeile, ein spürbarer Unterschied. Der Aufbau bleibt sonst unverändert: Die Seitennummer steht im Schlüssel, weil jede Seite eigene Daten sind.
12:50 Was die Einstellung ändert, ist nur das Verhalten während des Ladens — statt in den leeren Ladezustand zu fallen, bleiben die alten Daten stehen und werden als veraltet markiert. Sie können diese Markierung nutzen, um die Tabelle dezent abzudunkeln. Das ist die ehrlichste Rückmeldung: Es passiert etwas, aber Sie verlieren nichts aus dem Blick.
13:10 Bauen Sie eine Liste, durch die man angenehm blättert. Der Prüfstein für das Vorausladen ist schön konkret: Beim Klick auf "weiter" sollte die nächste Seite meist schon da sein. Drosseln Sie die Verbindung im Browser-Werkzeug, sonst sehen Sie den Unterschied gar nicht — im lokalen Netz ist alles sofort da. Wer die Zusatzaufgabe angeht, stellt auf endloses Nachladen um und merkt dabei, dass die Rückgabe der nächsten Seitenkennung der einzig knifflige Teil daran ist.
13:36 Der dritte Punkt verdient eine Empfehlung, die man einmal zentral setzen sollte. Standardmäßig werden fehlgeschlagene Abfragen mehrfach wiederholt. Bei einem Netzaussetzer ist das goldrichtig. Bei einer abgelehnten Berechtigung ist es sinnlos — der Server wird auch beim vierten Mal ablehnen, und der Nutzer wartet vier Anläufe lang auf eine Fehlermeldung, die sofort feststand.
13:58 Fehler in der Vierhunderter-Gruppe sollten deshalb nicht wiederholt werden. Eine Zeile in den zentralen Voreinstellungen.
Praxis, Testing & Ausblick
14:05 Zum Abschluss die Fragen, die im echten Projekt entscheiden: Wie ordnet man das alles so, dass es nach einem Jahr noch trägt? Wie testet man es verlässlich? Und was ändert sich, wenn schon auf dem Server gerendert wird? Diese drei Fragen beantwortet keine Dokumentation für Sie; sie hängen an Ihrem Projekt und lohnen deshalb eine bewusste Entscheidung.
14:26 Die Empfehlung mit den eigenen Hooks ist die wichtigste Strukturregel für dieses Werkzeug. Eine Komponente sollte nicht wissen, unter welchem Schlüssel Daten liegen oder welche Adresse angesprochen wird — sie sollte sagen können: Gib mir die offenen Aufgaben. Alles Weitere liegt eine Schicht tiefer. Der Nutzen zeigt sich bei der ersten Schnittstellenänderung: Sie passen eine Datei an statt vierzig.
14:48 Und Ihre Komponenten lassen sich testen, ohne dass ein Zwischenspeicher-Aufbau nötig wäre. Der dritte Punkt ist ein praktischer Tipp, der viel Frust erspart. In Tests sollten fehlgeschlagene Abfragen nicht wiederholt werden. Sonst dauert jeder Test eines Fehlerfalls mehrere Sekunden, weil brav dreimal nachgefragt wird — und gelegentlich schlägt er wegen Zeitüberschreitung fehl, ohne dass etwas kaputt ist.
15:11 Ein eigener Zwischenspeicher-Aufbau für Tests, in dem das abgeschaltet ist, macht die Testsuite schnell und verlässlich. Das ist eine dieser Kleinigkeiten, die den Ruf einer Testsuite retten. Der zweite Schritt verdient eine Empfehlung. Setzen Sie vernünftige Voreinstellungen einmal zentral, statt sie bei jeder Abfrage zu wiederholen — etwa eine Grundfrische von einer Minute und die eben besprochene Regel zum Nichtwiederholen von Berechtigungsfehlern.
15:37 Damit verhalten sich neue Abfragen von selbst richtig, und Sie weichen nur da ab, wo es einen Grund gibt. Der letzte Punkt betrifft Projekte mit Server-Rendering: Die Daten werden dort schon geholt und wandern fertig in den Zwischenspeicher des Browsers. Wenige Zeilen mit großer struktureller Wirkung. Schauen Sie sich den unteren Teil an: Die Komponente kennt weder Schlüssel noch Adresse noch Ladefunktion.
16:00 Sie fragt nach offenen Aufgaben und bekommt sie. Das ist die Grenze, an der Ihre Anwendung von der Schnittstelle entkoppelt wird. Ein netter Nebeneffekt: Diese Hooks sind hervorragend benennbar und werden damit zur Dokumentation Ihrer Datenschicht — man sieht in einer Datei, welche Daten es überhaupt gibt. Zum Abschluss kapseln und testen Sie. Beim Testen achten Sie bitte auf den Ansatzpunkt: Der Server wird auf Netzwerkebene abgefangen, nicht Ihre Funktionen werden ersetzt.
16:27 Der Unterschied ist entscheidend — im ersten Fall läuft Ihr echter Datenweg mit allen Feinheiten, im zweiten testen Sie vor allem Ihre Attrappe. Und stellen Sie den Test-Zwischenspeicher auf keine Wiederholungen um, sonst wundern Sie sich über langsame Tests. Der erste Punkt ist die Strukturempfehlung, die wir eben besprochen haben — sie klingt nach Kosmetik und ist der Unterschied zwischen einer wartbaren und einer verstreuten Datenschicht.
16:52 Der zweite ist die Testfalle mit den Wiederholungen, und der dritte die alte Regel: Tests, die echte Server brauchen, schlagen irgendwann fehl, ohne dass jemand etwas kaputt gemacht hat. Danach vertraut niemand mehr der Testsuite — und dann ist sie wertlos, egal wie gut sie geschrieben ist. Fassen wir zusammen. Der Kern ist die Unterscheidung vom Anfang: Serverdaten werden zwischengespeichert, nicht verwaltet.
17:15 Der Schlüssel ist die Abhängigkeitsliste und gehört in eine zentrale Stelle; die beiden Zeitangaben setzen Sie bewusst statt sie zu übernehmen. Nach dem Schreiben ist das Ungültigmachen der sichere Standard, und wo es sich lohnt, kommt die optimistische Variante dazu — mit Rückweg. Und die Struktur darüber sind eigene Hooks, hinter denen die Schnittstelle verschwindet.
Fragen & Weiterarbeiten
17:37 Alle Hooks und Übungslösungen finden Sie in der Freigabe — die Schlüssel-Zentrale und die eigenen Hooks sind die beiden Bausteine, die ich Ihnen ans Herz lege. Die offizielle Dokumentation ist umfangreich und gut sortiert; daneben gibt es einen vielgelesenen Fachblog aus dem Umfeld des Projekts, der die typischen Denkfehler ausführlicher behandelt, als es eine Dokumentation kann.
17:58 Wenn bei Ihnen eine Frage zum Zwischenspeicher aufkommt, melden Sie sich gern. Vielen Dank für Ihre Aufmerksamkeit.
Lieber mit Trainer? Dieses Modul ist Teil unserer Team-Schulungen — mit Übungen, Ihrem eigenen Code und Fragen, die ein Video nicht beantwortet. Mehr erfahren →