從核心來看,TanStack Query 會根據查詢鍵 (query keys) 為你管理查詢快取 (query caching)。查詢鍵在頂層必須是一個陣列 (Array),可以簡單到只包含單一字串的陣列,也可以複雜到包含多個字串和巢狀物件。只要查詢鍵是可序列化 (serializable) 的,並且對查詢資料具有唯一性,你就可以使用它!
最簡單的鍵形式是由常數值組成的陣列。這種格式適用於:
// 待辦事項列表
injectQuery(() => ({ queryKey: ['todos'], ... }))
// 其他任何東西!
injectQuery(() => ({ queryKey: ['something', 'special'], ... }))
// 待辦事項列表
injectQuery(() => ({ queryKey: ['todos'], ... }))
// 其他任何東西!
injectQuery(() => ({ queryKey: ['something', 'special'], ... }))
當查詢需要更多資訊來唯一描述其資料時,你可以使用包含字串和任意數量可序列化物件的陣列來描述。這適用於:
// 單個待辦事項
injectQuery(() => ({queryKey: ['todo', 5], ...}))
// 以「預覽」格式顯示的單個待辦事項
injectQuery(() => ({queryKey: ['todo', 5, {preview: true}], ...}))
// 標記為「完成」的待辦事項列表
injectQuery(() => ({queryKey: ['todos', {type: 'done'}], ...}))
// 單個待辦事項
injectQuery(() => ({queryKey: ['todo', 5], ...}))
// 以「預覽」格式顯示的單個待辦事項
injectQuery(() => ({queryKey: ['todo', 5, {preview: true}], ...}))
// 標記為「完成」的待辦事項列表
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 章節。