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:

  • Sie wird als stale markiert. Dieser stale Zustand überschreibt alle staleTime-Konfigurationen, die in injectQuery oder verwandten Funktionen verwendet werden.
  • Wenn die Query gerade über injectQuery oder verwandte Funktionen gerendert wird, wird sie auch im Hintergrund erneut abgerufen.

Abgleichen von Queries mit invalidateQueries

Bei der Verwendung von APIs wie invalidateQueries und removeQueries (und anderen, die partielles Query-Matching unterstützen) können Sie mehrere Queries anhand ihres Präfixes abgleichen oder sehr spezifisch werden und eine exakte Query abgleichen. Informationen zu den Arten von Filtern, die Sie verwenden können, finden Sie unter Query-Filter.

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.

ts
import { injectQuery, QueryClient } from '@tanstack/angular-query-experimental'

class QueryInvalidationExample {
  queryClient = inject(QueryClient)

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

  // Both queries below will be invalidated
  todoListQuery = injectQuery(() => ({
    queryKey: ['todos'],
    queryFn: fetchTodoList,
  }))
  todoListQuery = injectQuery(() => ({
    queryKey: ['todos', { page: 1 }],
    queryFn: fetchTodoList,
  }))
}
import { injectQuery, QueryClient } from '@tanstack/angular-query-experimental'

class QueryInvalidationExample {
  queryClient = inject(QueryClient)

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

  // Both queries below will be invalidated
  todoListQuery = injectQuery(() => ({
    queryKey: ['todos'],
    queryFn: fetchTodoList,
  }))
  todoListQuery = injectQuery(() => ({
    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.

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

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

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

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

// However, the following query below will NOT be invalidated
todoListQuery = injectQuery(() => ({
  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.

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

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

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

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

// However, the following query below will NOT be invalidated
const todoListQuery = injectQuery(() => ({
  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.

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

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

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

// However, the following query below will NOT be invalidated
todoListQuery = injectQuery(() => ({
  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
todoListQuery = injectQuery(() => ({
  queryKey: ['todos', { version: 20 }],
  queryFn: fetchTodoList,
}))

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

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