Startseite / Artikel / Detaillierte Anleitung zu TanStack Query: Abfragen, Cache, Mutationen und optimistische Benutzeroberflächen.

Detaillierte Anleitung zu TanStack Query: Abfragen, Cache, Mutationen und optimistische Benutzeroberflächen.

TanStack Query verwaltet den Serverzustand wie ein Restaurantleiter: gemeinsame Cache-Schlüssel, Frischheitsregler, koordinierte Mutationen, Invalidation sowie optimistische Aktualisierungen über Ihrem HTTP-Client.

5069 Wörter

Das heutige Thema ist TanStack Query (früher React Query): die Bibliothek, die das unübersichtliche Abrufen von Server-Daten in vorhersehbare Workflows für Cache, Aktualität und Änderungen umwandelt. Eine Analogie mit einem hochwertigen Restaurant macht die beteiligten Komponenten leichter verständlich – der Speisesaal als UI, die Küche als Backend, die Kellner als HTTP-Client und der Manager als TanStack Query.

Was ist TanStack Query?

In einer typischen Anwendung bittet die UI den Backend um Daten mithilfe von fetch oder Axios. Diese Client-Tools sind bei der Koordination nicht besonders klug. Wenn fünf Komponenten gleichzeitig dasselbe Menü anfordern, können fünf separate Besuche in der Küche nötig werden. Wenn jemand die Suppe des Tages bestellt und ein anderer Gast zehn Sekunden später fragt, muss ein naiver Kellner erneut in die Küche gehen. Dadurch wird der Server überlastet und das Servicetempo verlangsamt.

TanStack Query fungiert als Chefkellner und Restaurantmanager: Es koordiniert das Abrufen, Caching, Synchronisieren sowie Aktualisieren des Serverzustands, damit die Küche nicht mit identischen Anfragen belastet wird.

Axios / Fetch gegen TanStack Query

Anfänger glauben oft, TanStack Query ersetze Axios oder fetch. Das ist nicht der Fall.

  • Fetch und Axios sind die Kellner. Sie überbringen eine Anfrage in die Küche und bringen eine Antwort zurück. Sie erinnern sich nicht an frühere Anfragen, beurteilen die Frische der Informationen oder koordinieren andere Kellner.
  • TanStack Query ist der Manager. Es beauftragt die Kellner mit ihren Aufgaben. Es merkt sich, was zurückgekommen ist, ob die Informationen noch als aktuell gelten, welche Tische denselben Notizblock teilen und wann jemand zurückgeschickt werden muss, nachdem die Küche ein Gericht geändert hat.

Sie schreiben immer noch queryFn-Körper, die Axios oder fetch aufrufen. TanStack Query umhüllt diese Aufrufe mit Cache-Schlüsseln, Deduplizierung, Wiederholungsversuchen und Lifecycle-Hooks.

Was ist TanStack Query? (Funktionsübersicht)

Sechs Funktionen sind im täglichen React-Arbeitsalltag am wichtigsten:

1. Abfragen (useQuery): Datenerhaltung

Deklarative Lesevorgänge, die durch einen queryKey identifiziert werden und von einem queryFn ausgeführt werden.

2. Caching: Das „Gehirn“ des Managers

Die Ergebnisse werden im Speicher unter Verwendung des Abfrageschlüssels gespeichert, sodass mehrere Komponenten denselben Netzwerkaufruf teilen können.

3. Frische: staleTime gegenüber gcTime

staleTime bestimmt, wann als veraltet angesehen wird, dass Daten aus dem Cache neu heruntergeladen werden müssen. gcTime (Abfallentsorgung) legt fest, wie lange ungenutzte Cache-Einträge vor ihrer Löschung bestehen bleiben.

4. Mutationen (useMutation): Änderung der Daten

Schreibvorgänge – Erstellen, Aktualisieren, Löschen – werden auf Anfrage ausgeführt und nicht beim Initialisieren.

5. Invalidation von Abfragen: Löschen des Menüs

Nach einer erfolgreichen Mutation werden die damit verbundenen Abfragen als veraltet markiert, sodass die Benutzeroberfläche mit dem Server neu synchronisiert wird.

6. Optimistische Aktualisierungen: Das Michelin-Sterne-Erlebnis

Die Cache-Daten werden sofort aktualisiert, bei Fehlern rückgängig gemacht und schließlich durch eine endgültige Synchronisierung abgeschlossen.

Der Rest dieses Leitfadens erläutert jede dieser Funktionen anhand von Beispielen aus der Restaurantbranche sowie konkreter Codebeispiele.

1. Abfragen (useQuery): Abrufen des Menüs

Eine Abfrage legt fest, was man haben möchte und wie es beschafft werden soll:

import { useQuery } from '@tanstack/react-query';
import axios from 'axios';

// The waiter function (Axios)
const fetchMenu = async () => {
  const response = await axios.get('/api/menu');
  return response.data;
};

function MenuComponent() {
  // The Manager (TanStack Query) orchestrating the process
  const { data: menu, isLoading, isError, error } = useQuery({
    queryKey: ['menu'], // The label for this specific data
    queryFn: fetchMenu,  // The waiter doing the fetching
  });

  if (isLoading) return <div>Waiter is walking to the kitchen... Loading Menu...</div>;
  if (isError) return <div>The kitchen is on fire! Error: {error.message}</div>;

  return (
    <ul>
      {menu.map((item) => (
        <li key={item.id}>{item.name} - ${item.price}</li>
      ))}
    </ul>
  );
}

Der queryKey ist der Dateinamen im Notizblock des Managers – ['menu'], ['soup'], ['allergies', tableId]. Identische Schlüssel teilen den Cache und vermeiden doppelte Anfragen während der Verarbeitung. Der queryFn beschreibt den Ablauf für den Kellner: Er gibt ein Versprechen auf Daten zurück.

Während die erste Anfrage abgewickelt wird, ermöglichen die Flags isPending bzw. loading es der Benutzeroberfläche, Platzhalter anzuzeigen. Fehler werden über isError und error sichtbar. Erfolgreich abgerufte Daten werden in data bereitgestellt und bleiben für alle Komponenten zugänglich, die diesen Schlüssel beobachten.

Was ist eine Rennbedingung?

Die Restaurant-Analogie

Stellen Sie sich vor, zwei Gäste bestellen Suppe, während die Küche langsam reagiert. Eine späte Antwort für Tisch A darf die neuere Anfrage von Tisch B nicht überschreiben. Ohne Koordination gewinnt diejenige Anfrage, die zuletzt abgeschlossen wird – auch wenn sie veraltet ist.

Wie das in React (useEffect) funktioniert

Manuelles Abrufen mit useEffect vergisst oft die Abbruchlogik. Wenn man schnell zwischen Seiten wechselt, kann eine ältere Antwort den Zustand ändern, nachdem bereits eine neuere Anfrage gestartet wurde.

Wie TanStack Query dieses Problem löst

Die Bibliothek verfolgt die laufenden Abfragen nach Schlüssel, kann diese bei Unterstützung über AbortSignal abbrechen und sorgt dafür, dass die UI-Beobachter kohärente Cache-Änderungen sehen statt willkürlicher setState-Konflikte.

2. Caching: das Notizbuch des Managers

// Waiter function
const fetchMenu = async () => {
  console.log("Waiter is walking to the kitchen!"); // We can track how many times this runs
  const response = await axios.get('/api/menu');
  return response.data;
};

// Component 1: The Sidebar
function MenuSidebar() {
  const { data } = useQuery({ queryKey: ['menu'], queryFn: fetchMenu });
  return <div>We have {data?.length} items today!</div>;
}

// Component 2: The Main Display
function MenuMainDisplay() {
  const { data } = useQuery({ queryKey: ['menu'], queryFn: fetchMenu });
  return <div>{data?.map(item => <p>{item.name}</p>)}</div>;
}

Wenn die erste Komponente mit ['menu'] geladen wird, sendet der Manager einen Wartenden. Wenn Sekunden später eine zweite Komponente mit dem gleichen Schlüssel geladen wird, liest sie stattdessen aus dem Notizbuch, anstatt erneut nachzuschauen. Diese Deduplizierung sorgt dafür, dass Dashboards mit vielen Karten, die gemeinsame Benutzer- oder Konfigurationsabfragen nutzen, ohne eigene globale Speicher schnell reagieren.

Der Manager in Aktion (Schritt für Schritt)

  1. Komponente A wird geladen → Cache-Abfrage fehlgeschlagen → Netzwerk.
  2. Antwort eintrifft → Cache wird geschrieben → A wird dargestellt.
  3. Komponente B wird mit demselben Schlüssel geladen → Cache-Erfolg → B wird sofort dargestellt.
  4. Laut den Frische-Regeln kann später eine Hintergrund-Aufladung stattfinden, ohne die erste Darstellung von B zu blockieren.

Der Serverzustand gehört zu TanStack Query; der eigentliche Client-UI-Zustand (offenes Modal, ausgewählte Registerkarte) kann im React-Zustand oder in einem leichtgewichtigen Client-Speicher aufbewahrt werden.

3. Frische: Konfigurierung von staleTime und gcTime

1. staleTime: Ist diese Information noch aktuell?

const { data } = useQuery({
  queryKey: ['soup'],
  queryFn: fetchSoup,
  staleTime: 1000 * 60 * 30, // 30 minutes
});

Mit staleTime: 10_000 gelten Daten, die jünger als zehn Sekunden sind, als aktuell: Beim Neuladen werden sie ohne erneutes Abrufen wiederverwendet. Sobald sie veraltet sind, können Beobachter ein Hintergrundabrufen auslösen (beim Neuladen, beim Fokussieren des Fensters oder bei erneuter Verbindung – je nach Standardeinstellungen und Optionen). Wählen Sie den Wert für staleTime entsprechend der Volatilität des Domains aus: Die Liste der Tagesgerichte kann kurz sein, während Länderlisten länger sein können.

2. gcTime: Kann ich dieses Dokument wegwerfen?

const { data } = useQuery({
  queryKey: ['allergies', 'table4'],
  queryFn: fetchAllergies,
  gcTime: 1000 * 60 * 60 * 24, // Keep in memory for 24 hours
});

gcTime bestimmt, wie lange ein Cache-Eintrag nachdem alle Beobachter entfernt wurden, im Speicher bleibt. Ein kurzer gcTime befreit den Speicher schneller; ein längerer Wert sorgt dafür, dass Wiederbesuche sofort abgewickelt werden. Verwechseln Sie dies nicht mit staleTime: Veraltete Daten können weiterhin im Speicher bleiben, bis sie durch das Müllsammlungsverfahren entfernt werden.

Das ultimative Geheimnis: stale-while-revalidate

TanStack Query zeigt während des Hintergrund-Aufrufs gerne veraltete Daten an. Die Benutzer sehen sofort das letzte bekannte Menü; sobald die Küche Updates bestätigt, wird das Notizbuch aktualisiert. Genau dieses Muster sorgt dafür, dass die Bibliothek bei jedem Besuch schneller wirkt als herkömmliche Ladeindikatoren.

4. Mutationen (useMutation): Ein neues Gericht hinzufügen

Was ist eine Mutation?

Eine Mutation ändert den Serverzustand – beispielsweise durch das Aufgeben einer Bestellung, die Bearbeitung eines Profils oder das Löschen eines Kommentars.

Die Restaurant-Analogie: Das Aufgeben einer Bestellung

Kellner geben keine Bestellungen automatisch auf, sobald ein Gast Platz nimmt; sie warten auf eine klare Anfrage. Mutationen funktionieren genauso: Sie werden ausgeführt, wenn man mutate oder mutateAsync aufruft.

Der Code: Erstellung des Bestellformulars

import { useMutation } from '@tanstack/react-query';
import axios from 'axios';
import { useState } from 'react';

// 1. The Waiter Function (The actual network request)
const placeOrder = async (orderData) => {
  // We are using POST because we are creating a new order
  const response = await axios.post('/api/orders', orderData);
  return response.data;
};

function OrderForm() {
  const [dish, setDish] = useState('');

  // 2. The Manager orchestrating the mutation
  const mutation = useMutation({
    mutationFn: placeOrder,
    // We can also trigger side effects right here!
    onSuccess: (data) => {
      console.log("Chef says: Order confirmed!", data);
    },
    onError: (error) => {
      console.log("Chef says: We have a problem.", error.message);
    }
  });

  const handleSubmit = (e) => {
    e.preventDefault();
    // 3. Triggering the mutation and passing the variables
    mutation.mutate({ dishName: dish, tableNumber: 4 });
  };

  return (
    <form onSubmit={handleSubmit}>
      <input
        value={dish}
        onChange={(e) => setDish(e.target.value)}
        placeholder="What would you like?"
      />

      {/* Notice how we use isPending to disable the button so they don't double-order! */}
      <button type="submit" disabled={mutation.isPending}>
        {mutation.isPending ? 'Sending to Kitchen...' : 'Place Order'}
      </button>

      {/* Handling the feedback */}
      {mutation.isError && <p style={{ color: 'red' }}>Failed: {mutation.error.message}</p>}
      {mutation.isSuccess && <p style={{ color: 'green' }}>Order placed successfully!</p>}
    </form>
  );
}

Verschließen Sie onSuccess mit Feedback-Meldungen, Navigationselementen oder Validierungsmaßnahmen. Verwenden Sie mutateAsync, wenn Sie in Submit-Handlern auf die Abschlussbehandlung warten müssen.

Erweiterte Informationen für Entwickler

1. Es läuft nicht automatisch

Im Gegensatz zu Abfragen bleiben Mutationen untätig, bis sie aufgerufen werden – dadurch wird ein versehentlicher Schreibvorgang während der Darstellung verhindert.

2. isPending gegenüber isLoading

In v5 sollten Sie isPending für den Status einer laufenden Mutation bevorzugen. Stellen Sie die Deaktivierung der Benutzeroberfläche in Einklang mit diesem Flagge.

3. Vermeidung von Doppelklick-Problemen

Deaktivieren Sie die Senden-Schaltfläche, solange isPending wahr ist, damit Besucher keine doppelten Bestellungen aufgeben können.

5. Validierung von Abfragen: Anweisung an den Manager, das Notizbuch zu aktualisieren

Das Problem: das veraltete Notizbuch

Auch nachdem ein Koch ein Gericht hinzugefügt hat, sehen Tische, die weiterhin gespeicherte Menüs anzeigen, weiterhin die Liste vom Vortag, bis etwas neu geladen wird.

Die Lösung: Invalidation von Abfragen

import { useMutation, useQueryClient } from '@tanstack/react-query';
import axios from 'axios';

function AddDishForm() {
  // 1. Get access to the Manager's office
  const queryClient = useQueryClient();

  const mutation = useMutation({
    mutationFn: async (newDish) => {
      const response = await axios.post('/api/menu', newDish);
      return response.data;
    },
    // 2. The magic happens HERE in the onSuccess callback
    onSuccess: () => {
      // 3. Tell the Manager to rip up the menu notepad
      queryClient.invalidateQueries({ queryKey: ['menu'] });
      console.log("Menu invalidated! The Manager is getting a fresh copy.");
    },
  });

  // ... form code
}

invalidateQueries markiert die entsprechenden Einträge als veraltet und löst ein Neuladen für aktive Beobachter aus.

Was passiert genau, wenn man invalidateQueries aufruft?

Die entsprechenden Abfragen werden veraltet; die installierten Beobachter laden neu; die deinstallierten Einträge warten bis zum nächsten Installieren (unter Berücksichtigung von gcTime). Die Küche bleibt die Quelle der Wahrheit; dem Notizblock wird mitgeteilt, sich zu aktualisieren.

Das fortgeschrittene Konzept: Fuzzy-Matching

Eingeschränkte Invalidation:

queryClient.invalidateQueries({ queryKey: ['menu', 'lunch'] });

Oder ein ganzes Präfix für ungültig erklären:

// This rips up the breakfast, lunch, and dinner notepads all at once!
queryClient.invalidateQueries({ queryKey: ['menu'] });

Das ungenaue Präfixabgleich-Verfahren zerstört die Notizbücher für Frühstück, Mittagessen und Abendessen, wenn ['menu'] allgemein ungültig gemacht wird – mächtig und gefährlich. Wählen Sie lieber den engsten Schlüssel, der die Benutzeroberfläche korrekt hält.

Die goldene Regel der Mutationen

Jeder erfolgreiche Schreibvorgang sollte entweder die darauf angewiesenen Lesevorgänge ungültig machen oder den Cache präzise aktualisieren. Lesevorgänge unberührt zu lassen, führt dazu, dass die Benutzeroberflächen nach Speichern falsche Informationen anzeigen.

6. Optimistische Updates: Das Michelin-Sterne-Erlebnis

Die Analogie: Das Vertrauen des Managers

Ein vertrauenswürdiger Manager kann das neue Bier bereits vor der Bestätigung durch die Küche auf die Rechnung schreiben – und es wieder streichen, falls der Zapfhahn leer ist.

Die drei Säulen eines optimistischen Updates

Innen in useMutation:

  1. onMutate: Beenden Sie konkurrierende Abfragen, erstellen Sie einen Schnappschuss des Caches und schreiben Sie die optimistischen Daten umgehend hin.
  • onError: Stellen Sie den Snapshot wieder her, falls der Server die Anfrage ablehnt.
  • onSettled: Machen Sie den Inhalt ungültig (oder synchronisieren Sie ihn auf andere Weise), damit der Cache unabhängig davon, ob die Änderung erfolgreich war oder fehlschlug, mit der Datenbank übereinstimmt.
  • Der Code: Optimistisches Hinzufügen eines Gerichts

    import { useMutation, useQueryClient } from '@tanstack/react-query';
    import axios from 'axios';
    
    function AddDishForm() {
      const queryClient = useQueryClient();
    
      const mutation = useMutation({
        mutationFn: async (newDish) => {
          const response = await axios.post('/api/menu', newDish);
          return response.data;
        },
    
        // 1. The millisecond the user clicks submit...
        onMutate: async (newDish) => {
          // A. Cancel any outgoing refetches so they don't overwrite our optimistic update
          await queryClient.cancelQueries({ queryKey: ['menu'] });
    
          // B. Take a snapshot of the current menu (The Eraser Backup)
          const previousMenu = queryClient.getQueryData(['menu']);
    
          // C. Optimistically update the Manager's notepad right now!
          queryClient.setQueryData(['menu'], (oldMenu = []) => {
            // We fake an ID for now, the real ID comes from the database later
            return [...oldMenu, { ...newDish, id: Math.random().toString() }];
          });
    
          // D. Return the snapshot so onError can use it if things go wrong
          return { previousMenu };
        },
    
        // 2. If the Kitchen catches on fire...
        onError: (err, newDish, context) => {
          // Use the eraser! Roll back to the snapshot we saved in onMutate
          if (context?.previousMenu) {
            queryClient.setQueryData(['menu'], context.previousMenu);
          }
          console.error("Chef says no! Rolling back.", err);
        },
    
        // 3. Always run this at the very end, success or fail...
        onSettled: () => {
          // Tell the Manager to get the real, final menu from the database
          queryClient.invalidateQueries({ queryKey: ['menu'] });
        },
      });
    
      // ... form code
    }
    

    Achten Sie auf die Stornierung laufender Abfragen, die Struktur der Snapshots sowie die Rollback-Mechanismen. Eine optimistische Benutzeroberfläche wirkt sofortig, darf den Cache jedoch niemals in einer Sackgasse bringen, wenn die Küche eine Ablehnung signalisiert.

    Zusammenfügen der wichtigsten Elemente

    • TanStack Query ist ein asynchroner Zustandsmanager, kein Abfrager. Er umhüllt Axios/fetch, um das Netzwerkverhalten vorhersehbar zu machen.
    • Die Abfrageschlüssel sind entscheidend. Sie steuern die Deduplizierung, das Caching sowie den Austausch von Daten zwischen Komponenten.
  • Ihre Aufgabe ist die Synchronisierung des Caches nach Schreibvorgängen. Verwenden Sie invalidateQueries oder sorgfältig konstruierte optimistische Aktualisierungen, damit das Client-Notizbuch mit der Küche übereinstimmt.
  • Praktische Standardwerte für echte Anwendungen

    Beginnen Sie mit einem sinnvollen staleTime für überwiegend statische Ressourcen (in Minuten) sowie mit einem kurzen oder nullwertigen staleTime für benutzerbezogene, volatile Daten. Stellen Sie sicher, dass queryFn rein und abbruchfähig ist. Zentralisieren Sie Schlüssel in Factory-Funktionen (menuKeys.list(), menuKeys.detail(id)), damit die Invalidation typsicher und konsistent bleibt. Protokollieren Sie Cache-Ereignisse in der Entwicklung, um doppelte Abfragen zu diagnostizieren. Verzichten Sie vorerst auf aufwändige, manuell durchgeführte Cache-Operationen und bevorzugen Sie stattdessen Invalidation, es sei denn, ein Bildschirm benötigt tatsächlich optimistische Funktionalitäten.

    Häufige Fehlermuster

    • Durch die Verwendung instabiler Schlüssel (jedes Mal neue Objektliteralien bei der Darstellung) wird der Cache zerstört.
    • Wenn die Invalidation nach Mutationen vergessen wird, erscheinen falsche Daten.
    • Die Einstellung eines unendlichen staleTime ohne Strategie zur Handhabung von Mutationen führt dazu, dass die Benutzeroberflächen eingefroren bleiben.
    • Das Einbringen aller clientseitigen UI-Flags in den Query-Cache verwischt die Grenzen des Server-Zustands.
    • Eine zu weit gefasste Invalidation (Fehler im Stil von queryKey: ['']) führt dazu, dass der gesamte Inhalt neu geladen wird.

    Vermeiden Sie diese Probleme, dann funktioniert das Restaurant reibungslos: Die Kellner können bei Bedarf herumlaufen, das Notizbuch des Managers bleibt konsistent, und die Gäste sehen frisches Essen, ohne alle zehn Sekunden zur Küchentür schauen zu müssen.

    Fazit

    TanStack Query sichert sich seinen Platz, indem es die Lebenszyklen des Serverzustands – Lesevorgänge, Aktualität, Schreibvorgänge und Synchronisierung – steuert, während der Transport an Axios oder fetch überlassen wird. Lernen Sie die Einstellungsmöglichkeiten (Tasten), die Regler für die Aktualität (staleTime, gcTime) sowie die Verfahren zum Schreiben (Mutationen, Invalidation, optimistische Aktualisierungen). Damit müssen React-Apps nicht mehr in jedem useEffect eigene Anfragedatenpuffer entwickeln und verhalten sich stattdessen wie ein gut geführtes Restaurant.

    Warum die Restaurantmetapher weiterhin funktioniert

    Netzwerk-Wasserfälle erscheinen abstrakt, bis man sich fünf Kellner vorstellt, die um dieselbe Suppe rennen. Deduplizierung bedeutet, dass der Manager die Hand hebt: ein einziger Gang und viele Tische werden bedient. Stale-while-revalidate bedeutet, das letzte ausgedruckte Menü zu servieren, während ein Mitarbeiter die Tafel überprüft. Invalidation bedeutet, Seiten herauszureißen, wenn der Koch die Rezepte ändert. Optimistische Updates beinhalten das Aufschreiben der Bestellung des Gastes auf die Rechnung vor der Bestätigung – mit einem Radiergummi bereit. Bei der Einarbeitung von Junior-Mitarbeitern sollte man diese Szenarien vorstellen, bevor man auf TypeScript-Generics zu sprechen kommt; so bleibt das Verständnis besser haften.

    Integration mit Routern und Authentifizierung

    Sollten die Daten nicht global sein, müssen die Schlüssel die Identität des Mieters oder Benutzers enthalten: ['menu', restaurantId] oder ['allergies', userId]. Beim Ausloggen sollte der Cache geleert werden, um zu verhindern, dass Seiten des Notizbuchs zwischen verschiedenen Benutzern durchsickern. Mit React Router oder ähnlichen Tools sollte bei Aktionen, bei denen bereits bekannt ist, welche Ressourcen sich geändert haben, die Invalidation ausgelöst werden, anstatt bei jeder Navigation alles neu abzurufen.

    Teststrategien

    Unit-Tests für die queryFn-Mapper sollten unabhängig voneinander durchgeführt werden. In Komponententests sollten diese mit QueryClientProvider, einem frischen Client sowie retry: false zur Gewährleistung von Determinismus, umschlossen werden. Es muss überprüft werden, dass die Mutationen invalidateQueries mit den erwarteten Schlüsseln aufrufen. Bei optimistischen Ansätzen sollten Serverfehler simuliert werden, um sicherzustellen, dass der Zustand auf den letzten bekannten Wert zurückgesetzt wird. Es sollte vermieden werden, denselben QueryClient in unzusammenhängenden Tests ohne Zurücksetzung zu verwenden.

    Leistungshinweise

    Große Listen sollten hinter Paginierung oder endlosen Abfragen statt in einem einzigen Mega-Schlüssel untergebracht werden. Selektoren (select) ermöglichen es Komponenten, bestimmte Teile zu überwachen, ohne bei unverwandten Cache-Feldern neu rendern zu müssen. Stellen Sie sicher, dass die Ergebnisse von queryFn serialisierbar und stabil sind. Messen Sie Refetch-Stürme, wenn refetchOnWindowFocus auf sehr kurzen staleTime-Werten in stark genutzten Dashboards zum Tragen kommt – passen Sie die Einstellungen pro Abfrage an statt global.

    Migrationsdenken von rohen useEffect-Funktionen

    Ersetzen Sie Mount-Effekte, die Lade-, Fehler- und Datensätze setzen, durch useQuery. Ersetzen Sie imperative POST-Handler durch useMutation. Löschen Sie selbst erstellte Caches. Behalten Sie Axios-Instanzen für Interceptor-Funktionen und Auth-Header bei; übergeben Sie diese an queryFn. Die Migration erfolgt schrittweise: Eines nach dem anderen zu bearbeitende Screens reduzieren sofortige Race-Bugs.

    Letzte Überprülliste vor der Veröffentlichung einer Funktion

    1. Stabiler, hierarchischer queryKey.
    2. Für den Domainbereich wird ein expliziter staleTime gewählt.
    3. Mutation in Kombination mit Invalidation oder Optimismus-Strategie.
    4. Die laufende Benutzeroberfläche verhindert doppelte Übermittlungen.
    5. Fehlermeldungen sowie Grenzen sind korrekt implementiert.
    6. Schlüssel im Authentifizierungsrahmen werden am Ende der Sitzung gelöscht.

    Befolgt man diese sechs Punkte, wird TanStack Query nicht mehr zu „einer weiteren Bibliothek“, sondern zum idealen Manager, den Ihr Esszimmer benötigt.

    Durchgang: Laden eines Menüs über drei Komponenten

    Stellen Sie sich ein Header vor, das die Suppe des Tages anzeigt, einen Seitenbereich, der die Mittagsangebote auflistet, sowie ein Hauptfeld, das das komplette Menü darstellt. Ohne TanStack Query könnte jedes Feld seinen eigenen useEffect aufrufen und auf /api/menu zugreifen. Mit einem gemeinsamen queryKey: ['menu', restaurantId] wird die Netzwerkanfrage beim ersten Aufruf durchgeführt; die folgenden Aufrufe lesen den bereits gespeicherten Inhalt. Wenn der Koch die Suppe über ein Admin-Formular mithilfe von useMutation ändert, führt dies zur Ungültigstellung von ['menu', restaurantId] und aktualisiert somit alle noch angezeigten Felder. Die Gäste sehen niemals drei unterschiedliche Suppen, nur weil sich drei Kellner nicht einigen konnten.

    In dieser einen Konfiguration sind Deduplizierung, gemeinsamer Cache, Mutationen sowie Ungültigstellungen enthalten. Die meisten Produktionsseiten sind Variationen davon: Profil-Header zusammen mit Einstellungsformular, Warenkorb-Icon zusammen mit Bestellpositionen sowie Benachrichtigungs-Glocke zusammen mit der Benachrichtigungsebene.

    Abfrageschlüssel wie Dateipfade gestalten

    Betrachten Sie Schlüssel als hierarchische Pfade:

    • ['menu', restaurantId]
    • ['menu', restaurantId, 'lunch']
    • ['menu', restaurantId, 'item', itemId]
    • ['allergies', restaurantId, tableId]

    Fabriken helfen dabei:

    Durch die Inaktivierung von ['menu', restaurantId] kann bei entsprechender Konfiguration eine verschwommene Abgleichung tieferer Schlüssel erfolgen, wodurch Listen- und Detailansichten zusammen gespeichert werden können. Vermeiden Sie es, nicht serialisierbare Werte (Funktionen, Klasseninstanzen) in Schlüsseln zu embedden. Verwenden Sie lieber primitive IDs und stabile Enums.

    staleTime in Abhängigkeit von der Produktsprache wählen

    Fragen Sie die Produktverantwortlichen, wie falsch die Benutzeroberfläche möglicherweise über N Sekunden hinweg ist. Marketingtexte, die monatlich geändert werden, können eine längere Verfallszeit ertragen. Bestandszählungen während Schnäppchenverkäufen benötigen möglicherweise einen nahezu nullen staleTime sowie eine Außer Kraft Setzung bei jeder Kaufänderung. Dokumentieren Sie die gewählte Einstellung neben der Abfrage, damit zukünftige Bearbeiter eine volatile Abfrage nicht in ein langes Verfallsfenster „optimieren“.

    gcTime ist ein Regler für den Arbeitsspeicher. Mobile Apps mit vielen Routen profitieren davon, kürzlich angezeigte Bildschirme kurz zu speichern, damit die Rücknavigation sofortig wirkt. Extrem große Caches auf Geräten mit begrenztem Arbeitsspeicher erfordern kürzere gcTime-Werte oder Paginierung.

    Mutationen, die sich sicher anfühlen

    Zeigen Sie stets den Status „ausstehend“ sowie Fehlerzustände an. Deaktivieren Sie zerstörerische Schaltflächen, solange ein Vorgang aussteht. Bei Löschvorgängen sollte eine optimistische Löschung das Snapshot wiederherstellen, falls der Server 409 oder 500 zurückgibt. Bei Erstellvorgängen müssen optimistische Datensätze bei Erfolg temporäre Client-IDs durch Server-IDs ersetzen – oder man sollte auf die Optimismusstrategie verzichten und stattdessen die Daten ungültig machen, wenn die ID-Konvertierung schwierig ist.

    Parallel ablaufende Änderungen am selben Schlüssel können sich gegenseitig beeinträchtigen; stellen Sie sie in eine Warteschlange oder deaktivieren Sie die zugehörigen Steuerelemente. mutateAsync in Formbibliotheken sollte innerhalb von Submit-Handlern mit try/catch-Strukturen verwendet werden, nicht bei der Darstellung.

    Skalierbare Validierungsmuster

    Nach dem Anmelden sollten die benutzerbezogenen Schlüssel ungültig gemacht werden, anstatt den gesamten Client zu löschen, falls öffentliche Inhalte beibehalten werden sollen. Nach dem Abmelden ist in der Regel queryClient.clear() die richtige Vorgehensweise. Wenn ein WebSocket mitteilt, dass sich das Menü geändert hat, sollten die gleichen Ungültigmachungsfunktionen verwendet werden wie bei der HTTP-Änderung, damit beide Ansätze dieselbe Synchronisierungsstrategie teilen.

    Vorhalte für wahrscheinliche Detailseiten beim Überfahren: queryClient.prefetchQuery({ queryKey, queryFn }) wandelt wahrgenommene Latenz in Cache-Erfolge um, ohne den Screen-Code zu ändern.

    Optimistische Aktualisierungen ohne Mythologie

    Optimismus ist nicht für jeden POST erforderlich. Verwenden Sie ihn, wenn der erfolgreiche Ablauf häufig vorkommt, der Vorteil für die Benutzeroberfläche offensichtlich ist und ein Rollback einfach umsetzbar ist. Vermeiden Sie ihn, wenn die Servervalidierung komplex ist oder der Antwortkörper zur Darstellung benötigt wird (serverseitig generierte IDs, Preise, Steuern). Ein langsamer Ladeindikator kann freundlicher sein als ein plötzliches Auftauchen falscher Daten.

    Wenn Sie Optimismus nutzen, halten Sie die Snapshots unveränderlich, stornieren Sie kollidierende Abfragen in onMutate und synchronisieren Sie immer in onSettled. Protokollieren Sie Rollbacks im Entwicklungsmodus; stille Rollbacks verwirren die QA-Abteilung.

    Vergleich mit globalen Client-Speichern

    Redux oder Zustand können Serverdaten speichern, doch Sie müssen Caches neu erstellen, Duplikate abfragen und im Hintergrund aktualisieren. TanStack Query ist auf diesen Bereich spezialisiert. Behalten Sie vorübergehende UI-Elemente im lokalen Zustand oder in einem kleinen Client-Speicher bei; Serverentitäten sollten im Abfragespeicher aufbewahrt werden. Das Mischen dieser Ströme führt zu doppelten Quellen der Wahrheit.

    Das Team schulen

    Führen Sie ein Dojo durch: Erstellen Sie eine kleine Menü-App mit Listeabfrage, Detailabfrage, Erstellungsmutation, Invalidation sowie anschließender optimistischer Erstellung. Erfordern Sie Schlüsselgeneratoren sowie eine Funktion zum Ausloggen. Sobald dieses Muster zur Muskelgedächtnis-Funktion wird, sammeln größere Apps keine useEffect-Fetch-Fehler mehr an.

    Zusammenfassungstabelle in Prosa

    Abfragen werden gelesen. Mutationen werden geschrieben. Schlüssel benennen die Cache-Zeilen. staleTime beantwortet die Frage „Darf ich sie ohne Nachfrage erneut verwenden?“ gcTime beantwortet die Frage „Darf ich diese Notizseitenseite wegwerfen?“ Die Invalidation beantwortet mit „Die Küche hat sich geändert – aktualisieren.“ Der Optimismus antwortet mit „Aktualisieren Sie die Rechnung jetzt, löschen Sie sie bei Ablehnung.“ Für den Transport wird weiterhin Axios oder fetch verwendet. Diese Aufteilung der Aufgaben bildet das gesamte Produkt.

    Von Anfang bis Ende: Tafel mit Mittagsangeboten

    Ein Restaurant startet den Mittagsbetrieb. Die Abfrage für das Spezialitätenboard verwendet queryKey: ['menu', restaurantId, 'lunch'] mit einer staleTime von zwei Minuten, da Tafeln innerhalb eines Schichtzeitraums nur langsam aktualisiert werden. Das Widget für die Suppe im Header verwendet ['menu', restaurantId, 'soup'] mit einem Ablaufzeitraum von dreißig Sekunden. Beide queryFn-Funktionen rufen dieselbe Axios-Instanz mit Auth-Interceptoren auf. Wenn ein Administrator eine neue Suppe über useMutation speichert, setzt onSuccess beide Schlüssel außer Kraft – oder den gemeinsamen Präfix ['menu', restaurantId], falls eine ungenaue Abgleichung beabsichtigt ist. Gäste auf allen aktiven Tablets sehen die Aktualisierungen ohne manuelle Erneuerung.

    Falls das Administrator-Formular einen selbst erstellten fetch-Aufruf ohne Außer-Kraft-Setzen verwenden würde, würden die Tablets falsche Daten anzeigen, bis sie neu geladen werden. Genau dieses Problem soll mit TanStack Query vermieden werden.

    Query-Key-Fabriken in TypeScript

    Zentrale Schlüsselverwaltung:

    • menuKeys.all(restaurantId)
    • menuKeys.lunch(restaurantId)
    • menuKeys.item(restaurantId, itemId)

    Fabriken verhindern Tippfehler und ermöglichen eine Suche nach ungültigen Werten im Codebase. Verwenden Sie vorzugsweise Tupel aus Primitiven. Falls Filter vorhanden sind, fügen Sie serialisierte Filterobjekte mit stabiler Schlüsselreihenfolge hinzu. Fügen Sie niemals das gesamte Options-Objekt aus den Props in den Schlüssel ein, es sei denn, es ist gememorisert und serialisierbar.

    useQuery-Optionen, an denen Sie tatsächlich arbeiten werden

    Jenseits von queryKey und queryFn: enabled verhindert Abfragen, solange keine IDs vorhanden sind; retry steuert die Politik bei vorübergehenden Fehlern; refetchOnWindowFocus kann bei ressourcenintensiven Dashboards deaktiviert werden; placeholderData oder initialData sorgen für eine stabile Darstellung; select beschränkt die abonnierten Daten, um Wiederholte Darstellungen zu reduzieren. Die Standardwerte eignen sich zum Start; passen Sie sie je nach Abfrage an, wenn Profile Anzeichen von häufigen Neuladungen zeigen.

    Verständnis von „stale-while-revalidate“ aus UX-Sicht

    Die Anzeige des Einkaufswertes von gestern für 100 ms während einer Neuladung kann inakzeptabel sein; die Anzeige eines Artikels aus dem Hilfezentrum von gestern für eine Minute hingegen ist in Ordnung. Legen Sie dies in staleTime fest, nicht in ad-hoc-Flags. Ein fehlgeschlagenes Hintergrund-Neuladen sollte gute, veraltete Daten nicht löschen, es sei denn, Sie entscheiden sich ausdrücklich dafür; Nutzer bevorzugen eine leicht veraltete Information gegenüber einem Fehleranzeigefenster, wenn sie offline sind.

    Mutationen: Anatomie einer soliden Formulareingabe

    Deaktivieren Sie die Schaltfläche bei ausstehenden Vorgängen; zeigen Sie inline-Fehler aus error an; bei Erfolg ungültig machen oder den Cache aktualisieren; bei Abschluss ggf. den lokalen Formzustand löschen. Verwenden Sie mutateAsync mit try/catch innerhalb des Formularbibliothek-Submit-Handlers. Rufen Sie mutate nicht in Schleifen ohne Konkurrenzsteuerung auf. Bei Hochladen sollte der Fortschritt separat angezeigt werden – TanStack Query verfolgt den Mutationszustand, nicht den Byte-Fortschritt.

    Granularität der Ungültigmachung

    Zu eng: Die Liste wird aktualisiert, aber die Details vergessen → die Detailseite ist veraltet. Zu breit: Jeder Schlüssel unter ['menu'] wird neu geladen → massiver Ressourcenverbrauch. Passen Sie die Granularität den Bildschirmen an, die Inkonsistenzen anzeigen können. Im Zweifel ungültig machen Sie sowohl die Liste als auch den Detail-ID, den Sie geändert haben. Ein Präfix vor der Ungültigmachung dient einer bewussten Ausbreitung.

    Fallen bei optimistischen Aktualisierungen

    Der Snapshot muss eine ausreichend tiefe Struktur-Cloning durchführen, um verschachtelte Listen wiederherstellen zu können. Temporäre Client-IDs dürfen nicht an den Server durchsickern. Wenn mehrere optimistische Mutationen gleichzeitig ablaufen, können Rücksetzvorgänge sich gegenseitig stören – serialisieren Sie die Benutzeroberfläche für solche Abläufe. Vereinbaren Sie stets die Daten mit dem Stand auf dem Server, selbst nach einem Erfolg, da der Server Felder normalisieren könnte, die Sie nicht gesendet haben.

    React Strict Mode und doppelte Montage

    In der Entwicklung ruft Strict Mode die Effekte zweimal auf. TanStack Query entfernt Duplikate anhand der Schlüssel, sodass Sie für denselben Schlüssel während des Ablaufs keine doppelten Netzwerkaufrufe sehen sollten. Falls doch, ist Ihr Schlüssel instabil oder es gibt Probleme mit der Identität von queryFn, die die Annahmen zur Duplikatentfernung stören. Protokollieren Sie die Schlüssel beim Debuggen.

    SSR und Hinweise zur Hydratation

    Für Next.js und ähnliche Frameworks sollte der Query-Client auf dem Server entwässert und auf dem Client wieder befeuchtet werden, damit die Notizfunktion bei Navigationen weiterhin funktioniert. Stellen Sie sicher, dass queryFn-Funktionen in beiden Umgebungen ausgeführt werden, oder verwenden Sie serverseitiges Prefetching, um den Cache vor der Renderung zu füllen. Unterschiedliche Datenstrukturen zwischen Server und Client verursachen Warnungen bezüglich der Befeuchtung, die wie Fehler des Frameworks aussehen, in Wirklichkeit aber auf Probleme bei der Initialisierung des Caches zurückzuführen sind.

    Vergleich mit selbst implementierten SWR-Mustern

    Viele Teams entwickeln eigene Varianten dieser Bibliothek: Cache-Maps, gezieltes Neuladen, Mutieren und Neuvalidieren. TanStack Query standardisiert diese Ansätze mithilfe von Community-Standardlösungen und Devtools. Eine eigene Implementierung ist nur für sehr kleine Anwendungen oder ungewöhnliche Laufzeiten gerechtfertigt. Ansonsten gewinnt die Verwendung des vorgefertigten Frameworks aufgrund der eingesparten Zeit.

    Devtools und Überwachbarkeit

    Die React Query Devtools zeigen Schlüssel, Verfallsdatum, Beobachter sowie den Ladezustand an. Lehren Sie das Team, diese Informationen vor dem Hinzufügen von Konsoleausgaben zu lesen. In der Produktion sollten sensible Daten aus den Fehlerberichten entfernt werden; bei Bedarf nach Datenschutzvorgaben sollten Abfragerückfälle mit den Schlüsselnamen und nicht mit den vollständigen Datenpaketen protokolliert werden.

    Checkliste für Anti-Muster

    Instabile Schlüssel; fehlende Invalidation; endloses Verfallsdatum ohne Synchronisierung von Änderungen; Einfügen von UI-Flags in den Server-Cache; zu umfassende Invalidation; optimistische Aktualisierungen ohne Rückgängigmachung; Ignorieren des Parameters enabled solange IDs nicht vorhanden sind; Verwendung von Mutationen für Lesevorgänge. Vermeiden Sie diese Fehler, damit alles ordentlich bleibt.

    Zusammenfassung für Schnellleser

    Kellner übernehmen den Transport. Manager erinnern sich und koordinieren. Schlüssel sind Seiten in einem Notizblock. Regler für Frische steuern die Wiederverwendung. Mutationen werden gespeichert. Ungültigkeitsprüfungen und Optimismus sorgen dafür, dass der Notizblock zuverlässig bleibt. Das ist TanStack Query in Kürze – und der Grund, warum es Axios umhüllt statt es zu ersetzen.

    Zusätzliche Küchenübungen zum Üben

    Bauen Sie eine kleine Anwendung neu auf: Listeanfrage, Detailanfrage, Erstellung einer Mutation mit Ungültigkeitsprüfung sowie anschließend eine optimistische Erstellung mit erzwungener Fehlerbehandlung. Fügen Sie ein Ausloggen hinzu, das den Client leert. Fügen Sie eine Vorausladefunktion beim Überfahren eines Listeneintrags hinzu. Messen Sie die Netzwerkaufrufe in Devtools vor und nach der Verwendung gemeinsamer Schlüssel. Diese Übungen vermitteln ein besseres Verständnis der Bibliothek als das bloße Lesen von API-Tabellen.

    Beim Prüfen von Pull Requests fragen Sie: Was ist der Schlüssel? Was bedeutet staleTime und warum? Was wird nach Schreibvorgängen ungültig? Verhindert die laufende UI-Darstellung doppelte Absendungen? Wenn die Antworten klar sind, wird die Funktion auch unter Last durch Konkurrenz und Navigation zuverlässig funktionieren.

    Vorablade-Muster, die sofortig wirken

    Vorabladen beim Überfahren einer Route, beim Fokussieren eines Tabs vor dem Klick des Benutzers oder nach dem Anmelden für die Standard-Dashboard-Anfrage. Das Vorabladen füllt den Cache, ohne einen Observer zu initialisieren. Wenn der Benutzer navigiert, findet useQuery bereits geladene Daten und überspringt das Lade-Skelett. Laden Sie die falsche Schlüsselwerte vor, verschwenden Sie Bandbreite; laden Sie die richtigen Schlüsselwerte vor, steigt die wahrgenommene Leistung, ohne den queryFn-Code ändern zu müssen.

    Kombinieren Sie das Vorabladen mit einem realistischen staleTime. Das Vorabladen von Daten, die sofort veraltet sind, löst ein sofortiges Hintergrund-Vorabladen aus – immer noch besser als ein Neustart, aber nicht kostenlos. Laden Sie Abfragen des kritischen Pfades vor; lassen Sie seltene Einstellungsseiten unberührt.

    Abhängige Abfragen und Kontrolle des Ablaufs

    Wenn eine Detailansicht eine ID aus einer Listeauswahl benötigt, verwenden Sie ein Gate mit enabled: !!selectedId. Wenn eine zweite Abfrage Daten von der ersten benötigt, verknüpfen Sie diese sorgfältig: Entweder verschachteln Sie die zweite Schlüsselangabe mit der ID des ersten Ergebnisses oder verwenden Sie eine einzige queryFn-Funktion, die beide Datensätze zurückgibt, sofern die API dies unterstützt. Wasserfallabfragen verschlechtern den TTI; parallele Abfragen mit gemeinsamen Authentifizierungs-Header sind vorzuziehen, wenn dies durch Unabhängigkeit möglich ist.

    Der Suspense-Modus verändert die Art und Weise, wie Ladegrenzen zusammengesetzt werden. Wenn das Team Suspense verwendet, sollten Fehlergrenzen abgestimmt sein und sicherstellen, dass Abfragenfehler wie erwartet ausgelöst werden. Eine Mischung aus Suspense und klassischen Ladeindikatoren verwirrt Prüfer – wählen Sie für jeden Route-Tree einen Stil.

    Seitenschaltung, endlose Abfragen und Cache-Seiten

    Listenseiten verwenden oft Seite-Parameter im Schlüssel: ['orders', { page, pageSize, status }]. Das Ändern der Seite erzeugt einen neuen Cache-Eintrag; behalten Sie mit placeholderData: keepPreviousData (oder dem entsprechenden Wert der aktuellen API) die vorherigen Daten bei, damit die Tabelle nicht plötzlich leer erscheint. Unendliche Abfragen fügen Seiten hinzu; machen Sie den Cache sorgfältig ungültig, damit die Scrollposition nicht unerwartet gelöscht wird. Wenn eine Mutation eine Zeile ändert, aktualisieren Sie den entsprechenden Seite-Eintrag oder machen Sie den gesamten Listeneintrag ungültig, je nach Empfindlichkeit der Sortierordnung.

    Fehlerbehebung und Benutzererfahrung bei erneuten Versuchen

    Standardmäßige Wiederholungsversuche helfen bei instabilen Mobilnetzen. Bei 401/403 sollten die Wiederholungsversuche deaktiviert und der Benutzer zum Anmelden geleitet werden. Bei 404 im Detailfall soll sofort ein Fehler gemeldet werden. Für fortgeschrittene Nutzer sollen failureCount und failureReason in den Support-Overlays angezeigt werden. Globale QueryCache-Listener können bei Fehlern jeweils pro Schlüssel eine Benachrichtigung anzeigen, anstatt pro Beobachter – so werden „Toast-Stürme“ vermieden, wenn fünf Komponenten denselben fehlerhaften Abfragen nutzen.

    Teststrategien

    In Unit-Tests sollte man den Test mit einem neuen QueryClient mit retry: false sowie einer kurzen Garbage Collection umgeben. Mocken Sie queryFn oder verwenden Sie MSW. Überprüfen Sie die Lade-, Erfolgs- und Fehlerzustände. Bei Mutationen soll geprüft werden, ob invalidateQueries mit dem erwarteten Schlüssel aufgerufen wurde. Integrationstests sollten sicherstellen, dass zwei Komponenten, die denselben Schlüssel teilen, nicht doppelt abfragen. Instabile Tests entstehen oft durch verbleibenden Cache zwischen den Testfällen – erstellen Sie daher pro Test einen neuen Client.

    Versionserweiterungen und API-Drift

    TanStack Query von v4 auf v5 hat einige Optionen umbenannt und die Standardwerte geändert. Beim Upgrade sollten Sie den Migrationsleitfaden lesen, das Devtools-Paket aktualisieren und die Verwendung von keepPreviousData / placeholderData erneut überprüfen. Pinnen Sie die Versionen in Lockfiles. Änderungen an der Struktur der Abfrageschlüssel gelten als brisant: Alte, aufgeladene Caches passen möglicherweise nach dem Deployment nicht mehr zu den neuen Schlüsseln – akzeptieren Sie in diesem Fall einen einmaligen kalten Cache oder versionieren Sie den Schlüsselvorspann.

    Einsatznotizen aus Produktionsincidenzen

    Eines Teams stieß auf doppelte POST-Anfragen, weil die Absenden-Schaltfläche weiterhin aktiv blieb, während isPending bei einer anderen Mutationseinheit wahr war. Ein anderes Team löschte beim Ausloggen versehentlich den gesamten Cache, indem es einen neuen Client erstellte, ohne die alte Provider-Referenz zu löschen. Ein drittes Team kodierte Benutzerobjekte in Schlüsseln und störte dadurch die strukturelle Zusammenarbeit. Schreiben Sie diese Erfahrungen in die Einarbeitungsdokumente, damit Neuzugänge nicht erneut über dieselben Fehler stolpern.

    Dokumentieren Sie die Standardeinstellungen Ihres Systems: den Standardwert für staleTime, welche Abfragen benutzerbezogen sind, wie das Ausloggen den Zustand löscht und wann optimistische Aktualisierungen erlaubt sind. Konsistenz ist wichtiger als Cleverness.

    Aufzeichnungen zu Incidents in der Produktion

    Ein Team stieß auf doppelte POST-Anfragen, weil die Absenden-Schaltfläche weiterhin aktiv blieb, während isPending bei einer anderen Mutationseinheit wahr war. Ein anderes Team löschte beim Ausloggen versehentlich den gesamten Cache, indem es einen neuen Client erstellte, ohne die alte Provider-Referenz zu löschen. Ein drittes Team kodierte Benutzerobjekte in Schlüsseln und störte dadurch die strukturelle Zusammenarbeit. Schreiben Sie diese Erfahrungen in die Einarbeitungsdokumente, damit Neuzugänge nicht erneut über dieselben Probleme stolpern.

    Dokumentieren Sie die Standardeinstellungen Ihres Systems: den Standardwert für staleTime, welche Abfragen benutzerbezogen sind, wie das Ausloggen den Zustand löscht und wann optimistische Aktualisierungen erlaubt sind. Konsistenz ist wichtiger als Cleverness.

    Aufzeichnungen zu Incidents in der Produktion

    Ein Team stieß auf doppelte POST-Anfragen, weil die Absenden-Schaltfläche weiterhin aktiv blieb, während isPending bei einer anderen Mutationseinheit wahr war. Ein anderes Team löschte beim Ausloggen versehentlich den gesamten Cache, indem es einen neuen Client erstellte, ohne die alte Provider-Referenz zu löschen. Ein drittes Team kodierte Benutzerobjekte in Schlüsseln und störte dadurch die strukturelle Zusammenarbeit. Schreiben Sie diese Erfahrungen in die Einarbeitungsdokumentation, damit Neuzugänge nicht erneut über dieselben Probleme stolpern.

    Dokumentieren Sie die Standardeinstellungen Ihres Systems: den Standardwert für staleTime, welche Abfragen benutzerbezogen sind, wie das Ausloggen den Zustand löscht und wann optimistische Aktualisierungen erlaubt sind. Konsistenz ist wichtiger als Cleverness.