Client vs. Server State
Why putting your API data into your global UI store is an anti-pattern, and how modern React separates the two.
The Two Types of State
**Client State (UI State):** Data that your React app completely owns. It is synchronous, temporary, and lost when you refresh the page. Examples: Is this dropdown open? Is dark mode on? What did the user type into this uncontrolled input?
**Server State (Remote Data):** Data that fundamentally belongs to a database on a server. It is asynchronous, persistent, and shared among many users. Examples: A list of products, a user's profile details.
The Redux Mistake
For years, React developers put *everything* into global state managers like Redux.
But putting Server State into Client State is a nightmare. Because it's asynchronous, you suddenly have to manage isLoading, isError, and data manually for every single API call. Worse, the moment you put the data in Redux, it is 'stale' (out of date), because someone else might have updated the database.
You end up writing hundreds of lines of code just to handle caching and background updates.
The Modern Split
Modern React architecture draws a hard line between these two:
1. **Use a UI Store (Zustand, Context) ONLY for Client State.** (e.g., setDarkMode(true))
2. **Use a Server Cache (React Query, SWR, Apollo) for Server State.** These tools aren't 'state managers'—they are caching layers that automatically handle loading states, error retries, background fetching, and cache invalidation.
The Great Divide
Compare the characteristics of Client State vs Server State. Notice how different the problems are that they need to solve.
Client State (UI)
Owned by the browser. Synchronous.
Lost on refresh.
Server State
Owned by the DB. Asynchronous.
Needs caching layer.
Client state (left) is fast, synchronous, and lives in memory. Server state (right) requires crossing a network boundary, handling loading states, and maintaining a local cache to stay perfectly synced.
Check yourself
Pick an answer to lock it in, then read why. Getting one wrong is part of how it sticks.
Remember this
- Client State is synchronous UI data (owned by the browser).
- Server State is asynchronous remote data (owned by the database).
- Never put Server State into a standard Client State manager (like Redux or
useState). - Use a dedicated caching tool like React Query to handle Server State.
- Once you separate them, your global UI state becomes drastically simpler.
Done with this concept?
Mark it complete to track your progress. No login needed.