TanStack Query 的核心在于根据查询键为您管理查询缓存。查询键在顶层必须是一个数组,可以很简单地只包含一个字符串,也可以复杂到包含多个字符串和嵌套对象的数组。只要查询键可以使用 JSON.stringify 进行序列化,并且对查询数据是唯一的,您就可以使用它!
最简单的键形式是包含常量值的数组。这种格式适用于
// A list of todos
injectQuery(() => ({ queryKey: ['todos'], ... }))
// Something else, whatever!
injectQuery(() => ({ queryKey: ['something', 'special'], ... }))
// A list of todos
injectQuery(() => ({ queryKey: ['todos'], ... }))
// Something else, whatever!
injectQuery(() => ({ queryKey: ['something', 'special'], ... }))
当查询需要更多信息来唯一描述其数据时,你可以使用包含一个字符串和任意数量可序列化对象的数组来描述它。这对于以下情况很有用
// An individual todo
injectQuery(() => ({queryKey: ['todo', 5], ...}))
// An individual todo in a "preview" format
injectQuery(() => ({queryKey: ['todo', 5, {preview: true}], ...}))
// A list of todos that are "done"
injectQuery(() => ({queryKey: ['todos', {type: 'done'}], ...}))
// An individual todo
injectQuery(() => ({queryKey: ['todo', 5], ...}))
// An individual todo in a "preview" format
injectQuery(() => ({queryKey: ['todo', 5, {preview: true}], ...}))
// A list of todos that are "done"
injectQuery(() => ({queryKey: ['todos', {type: 'done'}], ...}))
这意味着无论对象中键的顺序如何,以下所有查询都被认为是相等的
injectQuery(() => ({ queryKey: ['todos', { status, page }], ... }))
injectQuery(() => ({ queryKey: ['todos', { page, status }], ...}))
injectQuery(() => ({ queryKey: ['todos', { page, status, other: undefined }], ... }))
injectQuery(() => ({ queryKey: ['todos', { status, page }], ... }))
injectQuery(() => ({ queryKey: ['todos', { page, status }], ...}))
injectQuery(() => ({ queryKey: ['todos', { page, status, other: undefined }], ... }))
然而,以下查询键不相等。数组项的顺序很重要!
injectQuery(() => ({ queryKey: ['todos', status, page], ... }))
injectQuery(() => ({ queryKey: ['todos', page, status], ...}))
injectQuery(() => ({ queryKey: ['todos', undefined, page, status], ...}))
injectQuery(() => ({ queryKey: ['todos', status, page], ... }))
injectQuery(() => ({ queryKey: ['todos', page, status], ...}))
injectQuery(() => ({ queryKey: ['todos', undefined, page, status], ...}))
由于查询键唯一地描述了它们正在获取的数据,因此它们应该包含你在查询函数中使用的会发生变化的任何变量。例如
todoId = signal(-1)
injectQuery(() => ({
enabled: todoId() > 0,
queryKey: ['todos', todoId()],
queryFn: () => fetchTodoById(todoId()),
}))
todoId = signal(-1)
injectQuery(() => ({
enabled: todoId() > 0,
queryKey: ['todos', todoId()],
queryFn: () => fetchTodoById(todoId()),
}))
请注意,查询键充当您查询函数的依赖项。向查询键添加依赖变量将确保查询被独立缓存,并且任何时候变量发生变化,查询都会被自动重新获取(取决于您的 staleTime 设置)。有关更多信息和示例,请参阅 exhaustive-deps 部分。