InterviewHubPRO
Section Overview
Q330

Question 330 of 445

Part 10: Modern React 18, React 19 & Next.js Patterns (317 - 353)

74%
React & Modern Frontend (445 Qs)•Part 10: Modern React 18, React 19 & Next.js Patterns (317 - 353)

What is the difference between client state and server state?

Client state is data that lives entirely in the browser and is owned by the UI — it doesn't need to be synchronized with a backend. Server state is data that actually lives on a remote server/database; the client only holds a cached copy of it, which can go stale at any time.

AspectClient stateServer state
OwnershipOwned entirely by the UIOwned by the backend/database; UI only has a cached copy
ExamplesForm input values, modal open/closed, selected tab, theme, filters before submitFetched user profile, product list, comments, any REST/GraphQL response
PersistenceUsually reset on refresh (unless explicitly persisted)Persists on the server regardless of client refreshes
StalenessNever "stale" — it's the source of truth itselfCan become stale/out of date; needs refetching, caching, and invalidation
SharingTypically local to one component/featureOften shared across many components/screens
Async concernsNone — synchronous updates via setState/reducersRequires handling loading, error, retries, pagination, race conditions
Typical toolsuseState, useReducer, Context, Redux/ZustandReact Query / TanStack Query, RTK Query, SWR, Apollo Client

Why the distinction matters

Treating server state like client state (e.g., dumping a fetched API response into useState or a Redux slice and manually managing loading/error flags) reinvents caching, deduplication, background refetching, and invalidation by hand. Dedicated server-state libraries solve these problems out of the box:

jsx
// Server state handled manually — lots of boilerplate to get right
function Users() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);

useEffect(() => {
  fetch("/api/users")
    .then((res) => res.json())
    .then(setUsers)
    .catch(setError)
    .finally(() => setLoading(false));
}, []);
// ...
}
jsx
// Server state via React Query — caching, refetching, and status handled for you
function Users() {
const { data: users, isLoading, error } = useQuery({
  queryKey: ["users"],
  queryFn: () => fetch("/api/users").then((res) => res.json()),
});
// ...
}

In short, use local state/Context/Redux for client state (UI-only concerns), and a data-fetching library like React Query, RTK Query, or SWR for server state (anything that mirrors data owned by a backend).