TanStack Query's automatischer Sync: Daten aktuell halten
Takashi Yamamoto
Infrastructure Engineer · Leapcell

Einleitung
In der dynamischen Welt der Webentwicklung ist die Gewährleistung, dass die dem Benutzer angezeigten Daten stets aktuell und mit dem Backend-Server konsistent sind, eine anhaltende Herausforderung. Herkömmliche Ansätze beinhalten oft manuelles Datenabrufen, komplexes Zustandsmanagement oder häufige, potenziell ineffiziente Abfragemethoden. Diese Methoden können zu veralteten Benutzeroberflächen, erhöhter Serverlast und einer suboptimalen Benutzererfahrung führen. Hier glänzen moderne Datenabruffbibliotheken wie TanStack Query (ehemals React Query). TanStack Query wurde mit Blick auf die Entwicklererfahrung und Leistung entwickelt und bietet leistungsstarke Funktionen zur Verwaltung des Serverzustands, insbesondere seine intelligenten Fähigkeiten zur automatischen Synchronisierung und Aktualisierung von Daten im Hintergrund. Das Verständnis, wie diese automatische Synchronisierung erreicht wird, ist entscheidend für die Erstellung robuster, reaktionsschneller und effizienter Frontend-Anwendungen.
Kernkonzepte von TanStack Query
Bevor wir uns mit den Einzelheiten der automatischen Synchronisierung befassen, wollen wir ein grundlegendes Verständnis einiger Schlüsselkonzepte von TanStack Query schaffen:
- Query: Stellt eine asynchrone Anfrage zum Abrufen von Daten dar (z. B.
useQuery). Sie identifiziert die Daten eindeutig anhand eines "Query Key". - Query Key: Ein eindeutiger Bezeichner (ein Array oder eine Zeichenkette) für jedes Stück zwischengespeicherter Daten. So weiß TanStack Query, welche Daten was sind.
- Cache: TanStack Query verwaltet einen In-Memory-Cache mit aufgelösten Abfragen. Wenn Sie Daten mit einem bestimmten Query Key anfordern, prüft TanStack Query zuerst seinen Cache. Wenn die Daten verfügbar und nicht veraltet sind, werden sie sofort zurückgegeben.
- Stale Time: Die Dauer, nachdem zwischengespeicherte Daten als "veraltet" gelten. Sobald Daten veraltet sind, versucht TanStack Query, sie beim nächsten Mal, wenn darauf zugegriffen oder sie beobachtet werden, im Hintergrund erneut abzurufen.
- Cache Time: Die Dauer, nachdem inaktive zwischengespeicherte Abfragedaten aus dem Garbage Collector entfernt werden. Wenn eine Abfragekomponente unmontiert wird und die Daten nicht mehr beobachtet werden, verbleiben sie im Cache, bis
cacheTimeabläuft. - Refetching: Der Prozess der erneuten Ausführung einer Abfragefunktion, um die neuesten Daten vom Server abzurufen. Dies kann automatisch geschehen oder manuell ausgelöst werden.
- Background Refetching: Wenn TanStack Query Daten erneut abruft, ohne beim anfänglichen Rendern einen Lade-Spinner anzuzeigen, wodurch sich die Benutzeroberfläche schneller anfühlt. Benutzer sehen kurzzeitig veraltete Daten, bevor die neuen Daten eintreffen.
Das Prinzip der automatischen Synchronisierung
Die automatische Synchronisierung von TanStack Query basiert auf dem Prinzip "Stale-while-revalidate". Das bedeutet, dass TanStack Query, wenn die Daten einer Abfrage als veraltet gelten:
- Gibt sofort die zwischengespeicherten (veralteten) Daten an die Benutzeroberfläche zurück.
- Initiieren im Hintergrund einen erneuten Abrufvorgang, um die neuesten Daten vom Server zu erhalten.
- Nach Abschluss des erneuten Abrufs aktualisiert es den Cache mit den neuen Daten und rendert die Benutzeroberfläche mit den frischen Informationen neu.
Dieser elegante Mechanismus verhindert Flackern der Benutzeroberfläche durch Ladestatus und bietet den Benutzern eine sofortige Antwort, auch wenn die Daten vorübergehend veraltet sein könnten.
Mechanismen zur automatischen Datenaktualisierung
TanStack Query nutzt mehrere intelligente Mechanismen, um Ihre Daten automatisch abzurufen und zu synchronisieren, ohne explizite Abfragelogik:
1. Refetch on Window Focus
Dies ist vielleicht eine der leistungsfähigsten und oft übersehenen Funktionen. Wenn ein Benutzer Ihre Anwendung verlässt (z. B. den Tab wechselt, das Fenster minimiert) und dann zurückkehrt, ruft TanStack Query automatisch alle aktiven und veralteten Abfragen erneut ab. Dies stellt sicher, dass der Benutzer, wenn er sich wieder mit Ihrer App beschäftigt, die neuesten Daten erhält, und schließt die Lücke zu potenziellen Backend-Updates, die auftraten, während er weg war.
Beispiel:
import { useQuery } from '@tanstack/react-query'; import axios from 'axios'; interface Todo { id: number; title: string; completed: boolean; } const fetchTodos = async (): Promise<Todo[]> => { const { data } = await axios.get<Todo[]>('/api/todos'); return data; }; function TodoList() { const { data, isLoading, error } = useQuery<Todo[], Error>({ queryKey: ['todos'], queryFn: fetchTodos, staleTime: 5 * 60 * 1000, // Daten gelten nach 5 Minuten als veraltet // standardmäßig ist refetchOnWindowFocus true }); if (isLoading) return <div>Lade Todos...</div>; if (error) return <div>Fehler aufgetreten: {error.message}</div>; return ( <ul> {data?.map(todo => ( <li key={todo.id}>{todo.title} - {todo.completed ? 'Erledigt' : 'Ausstehend'}</li> ))} </ul> ); } export default TodoList;
In diesem Beispiel, wenn der Benutzer den Tab, auf dem TodoList gemountet ist, länger als 5 Minuten (staleTime) verlässt und dann zurückkehrt, ruft TanStack Query die todos automatisch im Hintergrund erneut ab.
2. Refetch on Mount
Wenn eine Instanz eines useQuery-Hooks gemountet wird und ihre Daten veraltet sind, initiiert TanStack Query automatisch einen Hintergrund-Abruf. Dies ist nützlich für Komponenten, die häufig gemountet und unmontiert werden, und stellt sicher, dass sie immer frische Daten anzeigen.
3. Refetch on Reconnect
Wenn die Netzwerkverbindung eines Benutzers unterbrochen wird und dann wiederhergestellt wird, erkennt TanStack Query dies intelligent und ruft automatisch alle aktiven und veralteten Abfragen erneut ab. Diese Funktion verbessert die Benutzererfahrung in Umgebungen mit intermittierender Konnektivität erheblich, da sich die Anwendung nach der Wiederverbindung automatisch "heilt".
4. Refetch on Interval (Polling)
Obwohl TanStack Query darauf abzielt, die Notwendigkeit manueller Abfragen zu reduzieren, bietet es eine Option, Daten in bestimmten Intervallen für Anwendungsfälle abzurufen, bei denen nahezu Echtzeit-Updates kritisch sind und andere Mechanismen nicht ausreichen.
Beispiel:
import { useQuery } from '@tanstack/react-query'; import axios from 'axios'; interface StockPrice { symbol: string; price: number; timestamp: string; } const fetchStockPrice = async (symbol: string): Promise<StockPrice> => { const { data } = await axios.get<StockPrice>(`/api/stock/${symbol}`); return data; }; function StockPriceDisplay({ symbol }: { symbol: string }) { const { data, isLoading, error } = useQuery<StockPrice, Error>({ queryKey: ['stockPrice', symbol], queryFn: () => fetchStockPrice(symbol), refetchInterval: 5000, // Alle 5 Sekunden erneut abrufen staleTime: Infinity, // Daten werden nicht von selbst veraltet, nur durch Intervall }); if (isLoading) return <div>Aktuellen Aktienkurs laden...</div>; if (error) return <div>Fehler aufgetreten: {error.message}</div>; return ( <div> <h3>{data?.symbol} Preis: ${data?.price.toFixed(2)}</h3> <p>Zuletzt aktualisiert: {new Date(data?.timestamp || '').toLocaleTimeString()}</p> </div> ); } export default StockPriceDisplay;
Hier wird der stockPrice für ein bestimmtes symbol alle 5 Sekunden erneut abgerufen, was eine nahezu Echtzeit-Aktualisierung bietet. Beachten Sie, dass staleTime: Infinity verwendet wird, da der refetchInterval hier der primäre Mechanismus für die Aktualität ist.
5. Manuelle Invalidierung und Mutationen
Während die oben genannten Mechanismen die automatische Hintergrundsynchronisierung behandeln, gibt es Zeiten, in denen Sie TanStack Query explizit mitteilen müssen, dass sich bestimmte Daten auf dem Server geändert haben und erneut abgerufen werden müssen. Dies ist besonders relevant, nachdem Aktionen wie das Erstellen, Aktualisieren oder Löschen von Ressourcen durchgeführt wurden.
queryClient.invalidateQueries(queryKey): Dies ist eine leistungsstarke Methode, um Abfragen, die einem queryKey entsprechen, als veraltet zu markieren. Sobald sie invalidiert sind, werden diese Abfragen beim nächsten Mal, wenn sie beobachtet/aufgerufen werden, im Hintergrund erneut abgerufen.
Beispiel mit Mutation:
import { useMutation, useQueryClient } from '@tanstack/react-query'; import axios from 'axios'; interface NewTodo { title: string; } interface CreatedTodo extends NewTodo { id: number; } const createTodo = async (newTodo: NewTodo): Promise<CreatedTodo> => { const { data } = await axios.post<CreatedTodo>('/api/todos', newTodo); return data; }; function AddTodoForm() { const queryClient = useQueryClient(); const mutation = useMutation<CreatedTodo, Error, NewTodo>({ mutationFn: createTodo, onSuccess: () => { // Invalidiere die 'todos'-Abfrage nach erfolgreicher Erstellung // Dies führt dazu, dass die TodoList-Komponente ihre Daten erneut abruft queryClient.invalidateQueries({ queryKey: ['todos'] }); }, }); const handleSubmit = (event: React.FormEvent) => { event.preventDefault(); const formData = new FormData(event.currentTarget as HTMLFormElement); const title = formData.get('title') as string; mutation.mutate({ title }); }; return ( <form onSubmit={handleSubmit}> <input name="title" placeholder="Titel des neuen Todos" /> <button type="submit" disabled={mutation.isPending}> {mutation.isPending ? 'Hinzufügen...' : 'Todo hinzufügen'} </button> {mutation.isError && <div>Fehler beim Hinzufügen des Todos: {mutation.error?.message}</div>} </form> ); } export default AddTodoForm;
In diesem Szenario wird nach der erfolgreichen Erstellung eines neuen Todos über AddTodoForm queryClient.invalidateQueries({ queryKey: ['todos'] }) aufgerufen. Dies teilt TanStack Query mit, dass die Daten, die mit dem Schlüssel ['todos'] (den unsere TodoList verwendet) verbunden sind, jetzt veraltet sind. Die TodoList löst dann automatisch einen Hintergrund-Abruf aus, um das neu hinzugefügte Todo anzuzeigen, ohne dass eine Seitenaktualisierung oder manuelle Zustandsaktualisierungen erforderlich sind.
Fazit
TanStack Query verändert grundlegend, wie wir Serverzustand in Frontend-Anwendungen verwalten, und bewegt uns weg von manueller Datensynchronisierung hin zu einem intelligenten, deklarativen Ansatz. Durch die Nutzung von Mechanismen wie Refetch on Window Focus, Mount, Reconnect und flexiblen Invalidierungsstrategien wird sichergestellt, dass die Benutzeroberfläche Ihrer Anwendung konsistent mit den Backend-Daten synchronisiert bleibt. Dies führt zu einer deutlich verbesserten Benutzererfahrung mit reaktionsschnellen Benutzeroberflächen, reduziertem Boilerplate-Code für Entwickler und letztendlich zu performanteren und wartbareren Anwendungen. Die Nutzung der automatischen Synchronisierungsfunktionen von TanStack Query ist ein wichtiger Schritt zum Aufbau wirklich moderner und dynamischer Web-Erlebnisse.

