State

state/query-key-deps

A TanStack Query key holds every variable its query function reads, so a new id fetches new data instead of showing the old.

seriousstaticfe-data-fetching

Why

The key is the cache address and the only thing TanStack Query watches. With queryKey: ['todo'] and queryFn: () => getTodo(id), every todo shares one cache entry: open todo 2 after todo 1 and the page shows todo 1's data, and changing id never refetches.

Fix

Put every value the query function uses into the key, in order from general to specific: queryKey: ['todo', id], ['todos', { status, page }]. In Vue pass the ref or getter itself (['todo', id]), not id.value. Build keys and functions together with queryOptions() or a key factory so they cannot drift apart, and enable @tanstack/query/exhaustive-deps in ESLint.

Examples

// bad
useQuery({ queryKey: ['todo'], queryFn: () => getTodo(todoId) })
// good
useQuery({ queryKey: ['todo', todoId], queryFn: () => getTodo(todoId) })

Sources

Facts

Id
state/query-key-deps
Severity
serious
Check
static checked in the source by audit
Applies to
jsx vue svelte
Only in projects with
tanstack-query
Taught by the skill
fe-data-fetching Data fetching
Since version
0.1.0

Rule file on GitHub

Read it in the terminal

npx github:dawidolko/frontend-skills explain state/query-key-deps