TanStack Query (React Query)
Manage server state with TanStack Query - automatic caching, background refetching, mutations with optimistic updates, and infinite scroll.
skill: TanStack Query (React Query) category: Web Development tags: [React Query, TanStack, Data Fetching, Caching, React] readingTime: 6
TanStack Query eliminates the entire loading/error/caching boilerplate of manual useEffect data fetching. It's not just a fetching library - it's a server state synchronization layer that keeps your UI consistent with the server automatically.
Workflow
- Fetch data with useQueryuseQuery replaces useEffect + useState data fetching with automatic loading/error states, caching, and background refetch.
- Mutate with useMutation and invalidationuseMutation handles create/update/delete operations with automatic error handling and cache invalidation after success.
- Implement optimistic updatesOptimistic updates show the result immediately before the server responds - making UIs feel instant.
- Load paginated data with useInfiniteQueryuseInfiniteQuery manages cursor/page-based pagination state - handles loading more data on scroll without manual state.
- Configure the QueryClientGlobal defaults prevent boilerplate per-query configuration. Proper devtools integration speeds debugging.
Output Format
TanStack Query: useQuery with queryKey + queryFn, useMutation with invalidateQueries, optimistic updates, and useInfiniteQuery for pagination.
useQuery({ queryKey: ['resource', id], queryFn: () => fetchResource(id) })
useMutation({ mutationFn: updateFn, onSuccess: () => invalidateQueries(...) })
useInfiniteQuery({ getNextPageParam: page => page.nextCursor })Examples
Input
Output
Edge Cases & Gotchas
- Query key design - Query keys are the cache keys. ['orders'] is too broad; ['orders', userId, { status }] is specific. Granular keys enable targeted invalidation.
- Parallel queries - Calling useQuery in a loop violates rules of hooks. Use useQueries for dynamic parallel queries: useQueries({ queries: ids.map(id => ({ queryKey: ['user', id], ... })) })
- Server-side rendering - In Next.js, prefetch queries on the server with queryClient.prefetchQuery then dehydrate to the client - avoids loading flicker on initial render.
- Enabled flag - Pass enabled: !!userId to skip the query until a required parameter is available - prevents fetching with undefined arguments.
When to Break These Rules
- Use SWR instead of TanStack Query for simpler use cases - SWR is lighter with a simpler API when you don't need mutations or infinite queries.
- Use RTK Query if you're already using Redux Toolkit - it's well integrated and avoids an extra dependency.
Reference Files
https://tanstack.com/query/latest/docshttps://tkdodo.eu/blog/practical-react-query