等待查询变为 stale 状态后再重新获取,并非总能奏效,尤其是当你因为用户执行了某些操作而确切知道查询数据已过时时。为此,QueryClient 提供了一个 invalidateQueries 方法,让你能够智能地将查询标记为 stale,并可能重新获取它们!
// 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 { useQuery, useQueryClient } from '@tanstack/solid-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/solid-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,
})
你甚至可以通过向 invalidateQueries 方法传递更具体的查询键来使带有特定变量的查询失效
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,
})
invalidateQueries API 非常灵活,因此即使你只想失效**没有其他变量或子键**的 todos 查询,你也可以向 invalidateQueries 方法传递一个 exact: true 选项。
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,
})
如果你发现自己想要**更细粒度**的控制,可以将一个断言函数传递给 invalidateQueries 方法。该函数将接收查询缓存中的每个 Query 实例,并允许你返回 true 或 false 来决定是否要使该查询失效。
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,
})