Managing Server State with React Query
Managing Server State with React Query
💡 Why Should You Learn This?
Concepts
React Query is a library that automates caching, synchronization, and revalidation of server state. It dramatically reduces repetitive fetch code and loading/error state management.
Why It Matters
React Query automatically handles 70% of server state management. You can declaratively implement caching, background revalidation, optimistic updates, and infinite scrolling.
Core Concepts
React Query Core Concepts
Query State Machine
Key Configuration
Cache Key Design Principles
Background Revalidation (stale-while-revalidate)
1. Immediately return cached data (fast response)
2. Fetch fresh data in the background
3. Update the UI when new data arrives
→ Users see previous data instantly instead of a blank screen
Key Points
- ▸stale-while-revalidate: return cache immediately + background revalidation
- ▸Query keys: hierarchical design enables bulk invalidation of related caches
- ▸useMutation + onMutate: improve UX with optimistic updates
- ▸useInfiniteQuery: declarative implementation of infinite scrolling
💡 ⚠️ Common Mistakes
- ▸Using a single string for queryKey — use an array for hierarchical structure to enable bulk invalidation of related caches
- ▸Not setting staleTime/cacheTime — default values trigger a refetch on every window focus; tune them to match your data characteristics
- ▸Forgetting invalidateQueries after useMutation — new items won't appear in lists; always invalidate related queries in onSuccess
- ▸Catching errors inside queryFn without rethrowing — React Query only handles error state when errors are thrown; always rethrow after catching
💡 🎯 Interview Prep
Q: What is the difference between React Query and Redux?
Q: Explain the difference between staleTime and cacheTime
Q: How do you implement optimistic updates?
Hint: Redux manages the entire client state, whereas React Query specializes in server state and automates caching, revalidation, and synchronization. staleTime is the duration during which data is considered fresh (no refetch occurs), while cacheTime is how long an inactive cache is kept in memory. Optimistic updates work by using setQueryData in onMutate to update the UI immediately, rolling back to the previous data in onError if something goes wrong, and re-syncing with server data in onSettled.