等待查询变为陈旧后再重新获取并不总是有效,特别是当您确切知道查询的数据由于用户的某些操作而过时时。为此,QueryClient 具有 invalidateQueries 方法,可让您智能地将查询标记为陈旧,并可能重新获取它们!
// 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'] })
注意:其他使用规范化缓存的库会尝试通过命令式或通过模式推断来更新本地查询的新数据,但 TanStack Query 为您提供了避免维护规范化缓存带来的人工劳动力的工具,而是提倡有针对性的失效,后台重新获取和最终的原子更新。
当使用 invalidateQueries 使查询失效时,会发生两件事
当使用像 invalidateQueries 和 removeQueries 这样的 API(以及其他支持部分查询匹配的 API)时,您可以通过它们的前缀匹配多个查询,或者非常具体地匹配一个确切的查询。有关您可以使用的过滤器类型的信息,请参阅查询过滤器。
在此示例中,我们可以使用 todos 前缀来使任何以 todos 开头的查询键失效
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,
}))
}
您甚至可以通过将更具体的查询键传递给 invalidateQueries 方法来使具有特定变量的查询失效
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,
}))
invalidateQueries API 非常灵活,因此即使您只想使仅 todos 查询失效,而这些查询没有任何更多的变量或子键,您也可以将 exact: true 选项传递给 invalidateQueries 方法
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,
}))
如果您发现自己想要更精细的粒度,您可以将谓词函数传递给 invalidateQueries 方法。此函数将接收来自查询缓存的每个 Query 实例,并允许您返回 true 或 false,以确定是否要使该查询失效
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,
}))