Files
dotfiles/dot_agents/skills/tanstack-query-best-practices/rules/qk-array-structure.md
T
Prad Nukala 6406208b35 shell: fish functions -> ~/.local/bin executables + bash/zsh ports; manage ~/.agents
- 16 cross-shell utilities converted to sh/bash chezmoi executables:
  ai c2p cp-appid extract_agents fab gdc gh-sonr-org-migrate ghg-clone
  ghn gho git-summary launch_omp_livediff_overlay lc-elir mdcp mdp pj
  (ghg-clone not named ghg: unrelated cargo binary owns that name)
- cwd/history helpers stay per-shell: yy c cd clip-last + ghg/ghn/gho
  cd-wrappers in bash/functions/ and zsh/functions/, loaded by rc files
- fish keeps only shell-state functions; converted ones now hit PATH
- cp-appid ignore gating moved to .local/bin path
- dot_agents/skills: 82 skills materialized from dotstate storage so
  dot_claude skill symlinks resolve on fresh bootstrap; dotstate
  profile/symlinks.json released .agents/skills .bashrc .zshrc
2026-08-10 15:15:06 -04:00

1.3 KiB

qk-array-structure: Always Use Arrays for Query Keys

Priority: CRITICAL

Explanation

Query keys must always be arrays at the top level. This enables proper caching, invalidation matching, and query deduplication. Using non-array keys will cause unexpected behavior and cache misses.

Bad Example

// Never use strings or non-array types as query keys
const { data } = useQuery({
  queryKey: 'todos',  // Wrong: string instead of array
  queryFn: fetchTodos,
})

const { data: user } = useQuery({
  queryKey: { id: 1, type: 'user' },  // Wrong: object instead of array
  queryFn: fetchUser,
})

Good Example

// Always use arrays for query keys
const { data } = useQuery({
  queryKey: ['todos'],
  queryFn: fetchTodos,
})

const { data: user } = useQuery({
  queryKey: ['user', 1],
  queryFn: () => fetchUser(1),
})

// Complex keys with objects inside arrays are fine
const { data: filteredTodos } = useQuery({
  queryKey: ['todos', { status: 'done', page: 1 }],
  queryFn: () => fetchTodos({ status: 'done', page: 1 }),
})

Context

  • Always applicable when defining query keys
  • Arrays enable prefix-based invalidation (e.g., invalidateQueries({ queryKey: ['todos'] }) matches all todo queries)
  • Object property order inside arrays doesn't matter for matching
  • Array element order does matter: ['todos', 1] !== ['1', 'todos']