skills/oakoss/agent-skills/tanstack-query

tanstack-query

SKILL.md

TanStack Query

Overview

TanStack Query is an async state manager, not a data fetching library. You provide a queryFn that returns a Promise; React Query handles caching, deduplication, background updates, and stale data management.

When to use: Infinite scrolling, offline-first apps, auto-refetching on focus/reconnect, complex cache invalidation, React Native, hybrid server/client apps.

When NOT to use: Purely synchronous state (useState/Zustand), normalized GraphQL caching (Apollo/urql), server-components-only apps (native fetch), simple fetch-and-display (server components).

Quick Reference

Pattern API Key Points
Basic query useQuery({ queryKey, queryFn }) Include params in queryKey
Suspense query useSuspenseQuery(options) No enabled option allowed
Parallel queries useQueries({ queries, combine }) Dynamic parallel fetching
Dependent query useQuery({ enabled: !!dep }) Wait for prerequisite data
Query options queryOptions({ queryKey, queryFn }) Reusable, type-safe config
Basic mutation useMutation({ mutationFn, onSuccess }) Invalidate on success
Mutation state useMutationState({ filters, select }) Cross-component mutation tracking
Optimistic update onMutate -> cancel -> snapshot -> set Rollback in onError
Infinite query useInfiniteQuery({ initialPageParam }) initialPageParam required in v5
Prefetch queryClient.prefetchQuery(options) Preload on hover/intent
Invalidation queryClient.invalidateQueries({ queryKey }) Fuzzy-matches by default, active only
Cancellation queryFn: ({ signal }) => fetch(url, { signal }) Auto-cancel on key change
Select transform select: (data) => data.filter(...) Structural sharing preserved
Skip token queryFn: id ? () => fetch(id) : skipToken Type-safe conditional disabling
Serial mutations useMutation({ scope: { id } }) Same scope ID runs mutations in serial

v5 Migration Quick Reference

v4 (Removed) v5 (Use Instead)
useQuery(key, fn, opts) useQuery({ queryKey, queryFn, ...opts })
cacheTime gcTime
isLoading (no data) isPending
keepPreviousData: true placeholderData: keepPreviousData
onSuccess/onError on queries useEffect or mutation callbacks
useErrorBoundary throwOnError
No initialPageParam initialPageParam required
Error type unknown Error type defaults to Error

Common Mistakes

Mistake Correct Pattern
Checking isPending before data Data-first: check data -> error -> isPending
Copying server state to local useState Use data directly or derived state pattern
Creating QueryClient in component Create once outside component or in useState
Using refetch() for parameter changes Include params in queryKey, let it refetch automatically
Same key for useQuery and useInfiniteQuery Use distinct key segments (different cache structures)
Inline select without memoization Extract to stable function or useCallback
Using catch without re-throwing Throw errors in queryFn (fetch doesn't reject on 4xx/5xx)
Manual generics on useQuery Type the queryFn return, let inference work
Destructuring query for type narrowing Keep query object intact for proper narrowing
Using enabled with useSuspenseQuery Use conditional rendering to mount/unmount component
Not awaiting prefetch for SSR Await prefetchQuery to avoid hydration mismatches
invalidateQueries not refetching all Use refetchType: 'all' for inactive queries

Delegation

  • Query pattern discovery: Use Explore agent
  • Cache strategy review: Use Task agent
  • Code review: Delegate to code-reviewer agent

If the tanstack-router skill is available, delegate route loader and preloading patterns to it. If the tanstack-form skill is available, delegate form submission and mutation coordination to it. If the tanstack-table skill is available, delegate server-side table patterns to it. If the tanstack-start skill is available, delegate server functions and SSR data loading to it. If the tanstack-devtools skill is available, delegate query cache debugging and inspection to it. If the tanstack-db skill is available, delegate reactive client-side database and live query patterns to it. If the tanstack-virtual skill is available, delegate list virtualization and infinite scroll rendering to it. If the tanstack-store skill is available, delegate shared client-side reactive state management to it. If the electricsql skill is available, delegate ElectricSQL real-time Postgres sync patterns to it. If the local-first skill is available, delegate local-first architecture decisions and sync engine selection to it.

References

Weekly Installs
31
GitHub Stars
4
First Seen
Feb 20, 2026
Installed on
claude-code29
opencode27
github-copilot27
codex27
kimi-cli27
gemini-cli27