Contents

Frontend Development › State Management & Data Fetching

Server State vs Client State

Cached copies of server data vs purely UI state.

Also known as: server state, client state, remote state vs local state, UI state vs server cache

Frontend state comes in two quite different kinds, and confusing them is the root of a lot of messy code.

Server stateClient state
What it isA copy of data that lives on the serverState that exists only in the browser
ExamplesOrders, user profile, product listIs the modal open? Which tab is selected? Draft text, sidebar collapsed
Who owns itThe server (the browser has a cache)The client
Can it become out of date?Yes: someone else may change itNo, you’re the only writer
Asynchronous?Yes: loading, errors, retriesUsually synchronous
Shared across components?OftenSometimes

Why the distinction matters

Server state has problems that client state doesn’t: staleness, loading and error states, caching, deduplicating requests, invalidation after changes, and synchronization with other users’ changes. If you store it in useState or a general global store, you end up hand-writing all of that:

// Typical hand-rolled version of server state
const [orders, setOrders] = useState([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
useEffect(() => { /* fetch, set... handle races, no cache, no refetch */ }, []);

A good division of labor

Once server data lives in a cache, what’s left for client state is usually small.

Rules of thumb

  • Don’t copy server data into local state. Read it from the cache. Two copies drift apart (single source of truth).
  • Derive what you can instead of storing it (derived state).
  • Decide for each piece of state: who owns it? If the server owns it, you’re managing a cache. If you own it, manage it locally.