Preface
One of the most misunderstood topics in React is state management.
Most problems start with a simple confusion:
“Is this client state or server state?”
TanStack React Query exists to make that distinction clear and intentional.
In this article, we’ll look at React Query from a practical and mental-model perspective:
- Why it exists
- What problems it solves
- How to think about server state
- How it’s used in real applications
No magic, no hype — just a clean and scalable approach.
What Is Server State?
Before touching any code, we need a clear definition.
Client State
- UI state
- Modal open/close
- Theme (dark/light)
- Form inputs
- Tabs, dropdowns, toggles
Server State
- Data fetched from an API
- Data shared across components
- Data that can become stale
- Data that needs revalidation
Server state is:
- Asynchronous
- Shared
- Potentially outdated
- Hard to keep in sync
TanStack React Query is built specifically to handle this kind of state.
Why TanStack React Query Exists
React Query does not try to replace state management libraries.
It doesn’t say:
“Let me manage all your state.”
Instead, it says:
“Don’t manually manage server state — I’ll do it for you.”
Out of the box, it handles:
- Loading states
- Error states
- Caching
- Background refetching
- Deduplication
- Retry logic
- Pagination and infinite queries
All without reducers, effects, or boilerplate.
Installing React Query
Setting Up the Query Client
Every React Query setup starts here.
Then wrap your app at the root:
At this point, React Query is globally available.
Your First Query A basic fetch function:
Using it inside a component:
Notice what’s missing:
- No
useEffect - No
useState - No manual loading flags
React Query owns the entire lifecycle.
Query Keys: The Core Concept
queryKey is the heart of React Query.
queryKey: ['users']
-
A query key acts as:
-
A cache identifier
-
A dependency system
-
A refetch trigger
With parameters:
This gives you:
-
Isolated cache per user
-
Automatic invalidation
-
Correct refetch behavior
Designing good query keys is one of the most important skills in React Query.
Caching and Stale Time
By default:
-
Data is cached
-
Data is considered stale immediately
You can tune this behavior:
This tells React Query:
"This data is fresh — don’t refetch yet."
Mutations: Writing Data
Fetching is only half the story.
Writing data happens through mutations.
Usage:
Key idea:
-
Mutations update the server
-
Queries stay in sync through invalidation
No manual refetching required.
Optimistic Updates
Sometimes you want instant UI feedback.
This gives you:
-
Instant UI updates
-
Automatic rollback on error
-
Much better user experience
Pagination and Infinite Queries
Pagination is a first-class feature.
Scroll-based loading, cursor pagination, and page-by-page fetching are all built in.
Common Mental Model Mistakes
Avoid these patterns:
❌ Putting server data into Redux or Zustand
❌ Fetching inside useEffect
❌ Manually syncing API responses
Preferred approach:
✅ Server state → React Query
✅ Client/UI state → useState / Zustand
✅ Cache & sync → React Query
Clear boundaries lead to clean architecture.
When NOT to Use React Query
React Query is not for everything.
Avoid it for:
-
Form input state
-
UI toggles
-
Modals
-
Theme preferences
It is designed only for server state.
Conclusion
TanStack React Query is more than a library — it’s a mental model.
Once you understand the difference between client state and server state:
-
Your code becomes simpler
-
Bugs decrease
-
Architecture improves
React Query teaches one powerful idea:
“Server state is not your state.”
And once that clicks, everything else follows.
Useful Links
