查询键

TanStack Query 的核心是基于查询键来为您管理查询缓存。查询键的顶层必须是数组,可以很简单地只包含一个字符串,也可以复杂地包含很多字符串和嵌套对象。只要查询键可以通过 JSON.stringify 进行序列化,并且对查询数据是唯一的,您就可以使用它!

简单查询键

最简单的键形式是包含常量值的数组。这种格式适用于

  • 通用列表/索引资源
  • 非层次结构资源
tsx
// A list of todos
useQuery({ queryKey: ['todos'], ... })

// Something else, whatever!
useQuery({ queryKey: ['something', 'special'], ... })
// A list of todos
useQuery({ queryKey: ['todos'], ... })

// Something else, whatever!
useQuery({ queryKey: ['something', 'special'], ... })

带变量的数组键

当查询需要更多信息来唯一描述其数据时,你可以使用包含一个字符串和任意数量可序列化对象的数组来描述它。这对于以下情况很有用

  • 分层或嵌套资源
    • 通常会传递 ID、索引或其他原始值来唯一标识项目
  • 带有附加参数的查询
    • 通常会传递一个包含附加选项的对象
tsx
// An individual todo
useQuery({ queryKey: ['todo', 5], ... })

// An individual todo in a "preview" format
useQuery({ queryKey: ['todo', 5, { preview: true }], ...})

// A list of todos that are "done"
useQuery({ queryKey: ['todos', { type: 'done' }], ... })
// An individual todo
useQuery({ queryKey: ['todo', 5], ... })

// An individual todo in a "preview" format
useQuery({ queryKey: ['todo', 5, { preview: true }], ...})

// A list of todos that are "done"
useQuery({ queryKey: ['todos', { type: 'done' }], ... })

查询键是确定性哈希的!

这意味着无论对象中键的顺序如何,以下所有查询都被认为是相等的

tsx
useQuery({ queryKey: ['todos', { status, page }], ... })
useQuery({ queryKey: ['todos', { page, status }], ...})
useQuery({ queryKey: ['todos', { page, status, other: undefined }], ... })
useQuery({ queryKey: ['todos', { status, page }], ... })
useQuery({ queryKey: ['todos', { page, status }], ...})
useQuery({ queryKey: ['todos', { page, status, other: undefined }], ... })

然而,以下查询键不相等。数组项的顺序很重要!

tsx
useQuery({ queryKey: ['todos', status, page], ... })
useQuery({ queryKey: ['todos', page, status], ...})
useQuery({ queryKey: ['todos', undefined, page, status], ...})
useQuery({ queryKey: ['todos', status, page], ... })
useQuery({ queryKey: ['todos', page, status], ...})
useQuery({ queryKey: ['todos', undefined, page, status], ...})

如果你的查询函数依赖于一个变量,请将其包含在你的查询键中

由于查询键唯一地描述了它们正在获取的数据,因此它们应该包含你在查询函数中使用的会发生变化的任何变量。例如

js
function useTodos(todoId) {
  const queryKey = ['todos', todoId]
  return useQuery({
    queryKey,
    queryFn: () => fetchTodoById(todoId.value),
  })
}
function useTodos(todoId) {
  const queryKey = ['todos', todoId]
  return useQuery({
    queryKey,
    queryFn: () => fetchTodoById(todoId.value),
  })
}

请注意,查询键充当查询函数的依赖项。在查询键中添加依赖变量将确保查询被独立缓存,并且任何时候变量发生变化,查询都会自动重新获取(取决于您的 staleTime 设置)。有关更多信息和示例,请参阅 exhaustive-deps 部分。

延伸阅读

有关在大型应用程序中组织查询键的技巧,请参阅 Effective React Query Keys,并查看社区资源中的 Query Key Factory Package