React Query (TanStack Query): Server State Caching
React Query (TanStack Query) is the standard solution for managing server state in React apps. It handles caching, request deduplication, background refetching, mutations, and optimistic updates with minimal boilerplate.
You tell it what data you want (query key). It fetches, caches, and keeps it fresh automatically. When you change data (mutation), it knows what to update or invalidate. You focus on UI; it handles the messy parts of server synchronization.
1Query Keys & Basic Usage
Query keys are the identity of your cached data. Use stable, hierarchical arrays. React Query automatically dedupes and caches based on these keys.
const { data, isLoading } = useQuery({
queryKey: ['user', userId],
queryFn: () => fetchUser(userId),
staleTime: 60_000
});2Caching Strategy (staleTime, gcTime)
staleTime controls how long data is considered fresh. gcTime controls how long inactive queries stay in memory.
3Mutations & Optimistic Updates
Use useMutation with invalidateQueries for correctness or setQueryData for instant UI. Optimistic updates provide rollback on error.
4Pagination & Infinite Scroll
Keep pagination params in query keys. Use useInfiniteQuery for infinite scrolling with getNextPageParam.
| Property | React Query | Manual Fetching |
|---|---|---|
| Best For | Server/API data | Simple cases |
| Features | Caching, deduping, background refetch, mutations | None built-in |
| Complexity | Low | High (you build everything) |
React Query
Best For
Server/API data
Features
Caching, deduping, background refetch, mutations
Complexity
Low
Manual Fetching
Best For
Simple cases
Features
None built-in
Complexity
High (you build everything)
Common questions
- ›“What is React Query and why use it?”
- ›“Explain staleTime vs gcTime.”
- ›“How do you handle optimistic updates?”
- ›“When would you use React Query vs Redux/Zustand?”
What interviewers look for
- Clear separation of server vs client state
- Understanding of query keys and invalidation
- Knowledge of optimistic updates with rollback
- Modern best practice (React Query for server state)
Short answer (60 sec)
React Query manages server state with automatic caching, deduplication, background refetching, and mutations. Use stable query keys, staleTime for freshness control, and invalidateQueries after mutations.
Detailed answer (senior level)
React Query owns server state. Use hierarchical query keys for cache identity. staleTime controls refetch frequency, gcTime controls memory cleanup. Mutations use invalidateQueries for correctness or setQueryData for instant UI. Optimistic updates provide rollback on error. This approach eliminates most manual loading/error state management and keeps UI fast and correct.
- Using unstable query keys (inline objects)
- Storing server data in Zustand/Redux instead of React Query
- Forgetting to invalidate after mutations
- Not using keepPreviousData in pagination
- Overusing staleTime: 0 (too many requests)
- ✓React Query is the standard for server state management
- ✓Query keys are the foundation of caching and invalidation
- ✓Use staleTime to control freshness, gcTime for memory
- ✓invalidateQueries for correctness, setQueryData for instant UX
- ✓Optimistic updates need proper rollback
- ✓Separate server state (React Query) from client state (Zustand/Context)
- ✓Always measure and tune based on real usage patterns