Framework
Version

Query-Ungültigmachung

Das Warten auf stale Queries, bevor sie erneut abgerufen werden, funktioniert nicht immer, insbesondere wenn Sie wissen, dass die Daten einer Query aufgrund einer Benutzeraktion veraltet sind. Zu diesem Zweck verfügt die QueryClient über eine Methode invalidateQueries, mit der Sie Queries intelligent als stale markieren und potenziell erneut abrufen können!

tsx
// Invalidate every query in the cache
queryClient.invalidateQueries()
// Invalidate every query with a key that starts with `todos`
queryClient.invalidateQueries({ queryKey: ['todos'] })
// Invalidate every query in the cache
queryClient.invalidateQueries()
// Invalidate every query with a key that starts with `todos`
queryClient.invalidateQueries({ queryKey: ['todos'] })

Hinweis: Wo andere Bibliotheken, die normalisierte Caches verwenden, versuchen würden, lokale Queries mit neuen Daten entweder imperativ oder über Schema-Inferenz zu aktualisieren, bietet TanStack Query Ihnen die Werkzeuge, um den manuellen Aufwand bei der Pflege normalisierter Caches zu vermeiden, und verschreibt stattdessen gezielt Invalidierung, Hintergrund-Neuerfassung und letztendlich atomare Updates.

Wenn eine Query mit invalidateQueries invalidiert wird, geschehen zwei Dinge:

  • Es ist als veraltet markiert. Dieser veraltete Zustand überschreibt jede staleTime-Konfiguration, die in useQuery oder verwandten Hooks verwendet wird.
  • Wenn die Abfrage gerade über useQuery oder verwandte Hooks gerendert wird, wird sie auch im Hintergrund neu abgerufen.

Abgleichen von Queries mit invalidateQueries

Bei der Verwendung von APIs wie invalidateQueries und removeQueries (und anderen, die teilweise Abfragen abgleichen), können Sie mehrere Abfragen anhand ihres Präfixes abgleichen oder sehr spezifisch werden und eine exakte Abfrage abgleichen. Informationen zu den Filtertypen, die Sie verwenden können, finden Sie unter Query Filters.

In diesem Beispiel können wir das Präfix todos verwenden, um alle Queries zu invalidieren, die mit todos in ihrem Query-Schlüssel beginnen.

tsx
import { useQuery, useQueryClient } from '@tanstack/react-query'

// Get QueryClient from the context
const queryClient = useQueryClient()

queryClient.invalidateQueries({ queryKey: ['todos'] })

// Both queries below will be invalidated
const todoListQuery = useQuery({
  queryKey: ['todos'],
  queryFn: fetchTodoList,
})
const todoListQuery = useQuery({
  queryKey: ['todos', { page: 1 }],
  queryFn: fetchTodoList,
})
import { useQuery, useQueryClient } from '@tanstack/react-query'

// Get QueryClient from the context
const queryClient = useQueryClient()

queryClient.invalidateQueries({ queryKey: ['todos'] })

// Both queries below will be invalidated
const todoListQuery = useQuery({
  queryKey: ['todos'],
  queryFn: fetchTodoList,
})
const todoListQuery = useQuery({
  queryKey: ['todos', { page: 1 }],
  queryFn: fetchTodoList,
})

Sie können sogar Queries mit spezifischen Variablen invalidieren, indem Sie einen spezifischeren Query-Schlüssel an die Methode invalidateQueries übergeben.

tsx
queryClient.invalidateQueries({
  queryKey: ['todos', { type: 'done' }],
})

// The query below will be invalidated
const todoListQuery = useQuery({
  queryKey: ['todos', { type: 'done' }],
  queryFn: fetchTodoList,
})

// However, the following query below will NOT be invalidated
const todoListQuery = useQuery({
  queryKey: ['todos'],
  queryFn: fetchTodoList,
})
queryClient.invalidateQueries({
  queryKey: ['todos', { type: 'done' }],
})

// The query below will be invalidated
const todoListQuery = useQuery({
  queryKey: ['todos', { type: 'done' }],
  queryFn: fetchTodoList,
})

// However, the following query below will NOT be invalidated
const todoListQuery = useQuery({
  queryKey: ['todos'],
  queryFn: fetchTodoList,
})

Die API invalidateQueries ist sehr flexibel. Selbst wenn Sie nur todos-Queries invalidieren möchten, die keine weiteren Variablen oder Unter-Schlüssel haben, können Sie die Option exact: true an die Methode invalidateQueries übergeben.

tsx
queryClient.invalidateQueries({
  queryKey: ['todos'],
  exact: true,
})

// The query below will be invalidated
const todoListQuery = useQuery({
  queryKey: ['todos'],
  queryFn: fetchTodoList,
})

// However, the following query below will NOT be invalidated
const todoListQuery = useQuery({
  queryKey: ['todos', { type: 'done' }],
  queryFn: fetchTodoList,
})
queryClient.invalidateQueries({
  queryKey: ['todos'],
  exact: true,
})

// The query below will be invalidated
const todoListQuery = useQuery({
  queryKey: ['todos'],
  queryFn: fetchTodoList,
})

// However, the following query below will NOT be invalidated
const todoListQuery = useQuery({
  queryKey: ['todos', { type: 'done' }],
  queryFn: fetchTodoList,
})

Wenn Sie feststellen, dass Sie noch mehr Granularität wünschen, können Sie eine Prädikatfunktion an die Methode invalidateQueries übergeben. Diese Funktion erhält jede Query-Instanz aus dem Query-Cache und ermöglicht es Ihnen, true oder false zurückzugeben, je nachdem, ob Sie diese Query invalidieren möchten.

tsx
queryClient.invalidateQueries({
  predicate: (query) =>
    query.queryKey[0] === 'todos' && query.queryKey[1]?.version >= 10,
})

// The query below will be invalidated
const todoListQuery = useQuery({
  queryKey: ['todos', { version: 20 }],
  queryFn: fetchTodoList,
})

// The query below will be invalidated
const todoListQuery = useQuery({
  queryKey: ['todos', { version: 10 }],
  queryFn: fetchTodoList,
})

// However, the following query below will NOT be invalidated
const todoListQuery = useQuery({
  queryKey: ['todos', { version: 5 }],
  queryFn: fetchTodoList,
})
queryClient.invalidateQueries({
  predicate: (query) =>
    query.queryKey[0] === 'todos' && query.queryKey[1]?.version >= 10,
})

// The query below will be invalidated
const todoListQuery = useQuery({
  queryKey: ['todos', { version: 20 }],
  queryFn: fetchTodoList,
})

// The query below will be invalidated
const todoListQuery = useQuery({
  queryKey: ['todos', { version: 10 }],
  queryFn: fetchTodoList,
})

// However, the following query below will NOT be invalidated
const todoListQuery = useQuery({
  queryKey: ['todos', { version: 5 }],
  queryFn: fetchTodoList,
})