Skip to main content

client-side state VS server-side state

Definitions

TermWhat it is
Client-side stateData that lives only in the browser, is managed by React itself, and exists independently of the server.
Server-side stateData that is stored on the server (in a database, an API, etc.) and must be loaded, updated, or synchronized with the client.

1. Client-side state

This is everything that exists only on the frontend, and React itself controls it through useState, useReducer, useContext, etc.

Examples of client state:

  • Whether a modal is open (isModalOpen)
  • The current filter or sort order
  • The selected tab
  • Text entered by the user but not yet submitted
  • Form validation
  • Theme state (dark / light)
  • Data in localStorage

This data does not need to be synchronized with the server. It lives in the browser's memory and disappears on page reload.


2. Server-side state

This is data that belongs to the server, and the client only loads, displays, and sometimes modifies it.

Examples:

  • A list of users from an API
  • Products in a store
  • User profile data
  • Comments on a post
  • Account balance
  • Any information stored in a database

This data:

  • is obtained asynchronously (fetch, axios, graphql, react-query, trpc),
  • can change on the server without the client's knowledge,
  • requires updating (refetching) on certain events.

3. Key differences

CharacteristicClient-side stateServer-side state
Where it is storedIn the browser's memoryOn the server / API
Who "owns" the dataThe clientThe server
How it updatesImmediately via setStateVia an HTTP request (fetch, axios, etc.)
Can it change "on its own"?NoYes (other users, processes)
Does it need to be synchronizedNoYes (via refetch or web sockets)
Examplesmodals, filters, current tablist of products, posts, user profile
Lost on reloadYesNo (data is preserved on the server)

Example for clarity

Client-side state

javascript
const [isModalOpen, setIsModalOpen] = useState(false);

The modal opens and closes - everything lives in React. The server doesn't care.


Server-side state

javascript
const [users, setUsers] = useState([]); useEffect(() => { fetch("/api/users") .then(res => res.json()) .then(setUsers); }, []);

Here the data comes from an external source (an API). If someone adds a new user, the server updates, but the client doesn't know yet, until it makes another request (a refetch).


4. Why it matters to separate these

  1. Different update requirements
  • Client state updates instantly via setState.
  • Server state requires a network request → asynchronous.
  1. Different tools
  • Client state → useState, useReducer, useContext, Zustand, Redux Toolkit.
  • Server state → React Query, SWR, Apollo, tRPC, RTK Query.
  1. Different "data lifetime"
  • Client state - lives as long as the component is mounted.
  • Server state - can be cached, refetched, invalidated.
  1. Different caching strategy
  • Client state: no point caching it, it's local UI data.
  • Server state: must be cached, so the API isn't hit on every render.

5. The modern approach: "divide and conquer"

Keep local state as close to the UI as possible (useState, useReducer, useContext)

And move server state into specialized tools that know how to:

  • cache requests,
  • refetch on changes,
  • synchronize data when a tab regains focus,
  • optimistically update the interface.

Examples:

javascript
React Query (TanStack Query) SWR (Next.js) Apollo Client (GraphQL) RTK Query (Redux)

Example with React Query

javascript
import { useQuery } from "@tanstack/react-query"; function UsersList() { const { data, isLoading, error } = useQuery({ queryKey: ["users"], queryFn: () => fetch("/api/users").then(res => res.json()), }); if (isLoading) return <p>Loading...</p>; if (error) return <p>Error!</p>; return ( <ul> {data.map(u => <li key={u.id}>{u.name}</li>)} </ul> ); }

Here data is server-side state, but React Query manages its caching, refetching, and synchronization.


Summary

Client-side stateServer-side state
Where it livesIn React / the browserOn the server
How it updatesImmediately (setState)Via a request
Can go stale without the client knowingNoYes
ToolsuseState, useReducer, useContext, ZustandReact Query, SWR, RTK Query, Apollo
Examplesmodal, filter, themeposts, products, profile
Needs refetchingNoYes
Render on updateImmediatelyAfter the server responds

A simple analogy

Client state is like a "draft" on your desk: you write notes, edit quickly, nothing gets synchronized.

Server state is like a document in the cloud (Google Docs): it is stored on the server, may change for other users, and you need time to get the up-to-date version.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.