React Curriculum

State Architecture: Taxonomy & Categorization

Medium100% Free~25 mins#react#state-management#architecture#taxonomy#server-state#url-state
Interview Answer (30-Second Summary)

Modern React state belongs to five distinct categories: local UI state (useState), shared client state (Zustand/Context), server cache state (TanStack Query), URL state (searchParams), and persistent device state (localStorage). Choosing the wrong bucket causes synchronization bugs and unnecessary re-renders.

Key Learning Objectives
✓

Classify application state into local, shared client, server cache, URL, and persistent categories.

✓

Recognize why caching remote API data in Redux or Context violates the single source of truth.

✓

Leverage URL search params as the authoritative state for pagination, filters, and modals.

✓

Design lean component architectures that avoid global state bloat.

The Interview Problem & Context

Given an e-commerce product search page with pagination, filters, a shopping cart, and search queries, how should each piece of state be categorized and managed?

1// Recommended state placement taxonomy
2interface AppStateArchitecture {
3 // 1. URL State: Bookmarkable, shareable, survives refreshes
4 // Handled by: useSearchParams / router
5 urlState: {
6 query: string; // ?q=laptop
7 page: number; // ?page=2
8 filterTag: string; // ?tag=electronics
9 };
10
11 // 2. Server Cache State: Asynchronous, owned by backend, needs invalidation
12 // Handled by: TanStack Query (React Query) / SWR / RTK Query
13 serverState: {
14 products: Array<{ id: string; name: string; price: number }>;
15 isLoading: boolean;
16 isStale: boolean;
17 };
18
19 // 3. Shared Global Client State: Ephemeral client-only domain state
20 // Handled by: Zustand / Context API
21 globalClientState: {
22 cartItems: Array<{ productId: string; quantity: number }>;
23 isCartDrawerOpen: boolean;
24 };
25
26 // 4. Local Component State: Isolated UI micro-interactions
27 // Handled by: useState / useReducer
28 localUIState: {
29 isHovered: boolean;
30 activeDropdownIndex: number | null;
31 };
32}
Deep Architectural Explanation

The 5 Types of State in Modern React

In early React applications, developers put every piece of state into a single monolithic Redux store. Modern frontend architecture categorizes state by its owner, lifetime, and synchronization requirements:

State TypeCharacteristicsRecommended Solution
URL StateBookmarkable, shareable via link, browser back/forwarduseSearchParams / Next.js router
Server StateOwned by backend, async fetch, caching, deduping, TTLTanStack Query, SWR, RTK Query
Global Client StateSynchronous, shared across unrelated branches, client-onlyZustand, Redux Toolkit, Context
Local UI StateScoped to a single widget or parent-child subtreeuseState, useReducer
Persistent StateSurvives browser close, tied to hardware/user devicelocalStorage, IndexedDB

Architectural Rule:

Never duplicate server state in client state. If the data originates from a REST or GraphQL endpoint, treat it as a remote cache using TanStack Query. Only store purely client-owned UI state in Zustand or Context.

Common Interview Traps & Pitfalls
✕

Duplicating filter and search values in useState instead of synchronizing with URL search params.

✕

Manually managing fetch, loading, error, and caching logic in global Redux slices.

✕

Lifting local UI state (like dropdown open/close) to global stores, triggering app-wide re-renders.

Senior Interviewer Follow-Up Probes
?

How does TanStack Query handle stale-while-revalidate caching under the hood?

?

When would you choose URL query parameters over local component state for a modal dialog?

?

What are the memory and re-render implications of keeping high-frequency state in React Context?

Frequently Asked Interview Questions
What is the main problem with putting server state in Redux or Context?

Server state is asynchronous and owned by the server. Storing it in Redux requires hundreds of lines of boilerplate for loading flags, error handling, manual cache invalidation, deduplication, and polling. Tools like TanStack Query handle this automatically.

Any state that determines what content is rendered and should be shareable or preserve history on browser back/forward navigation—such as pagination, sorting, search queries, active tab IDs, and open filter drawers.

Start local with useState at the lowest common ancestor in the tree. Only lift state up to global stores if two or more distant, decoupled components need to read or mutate the exact same data.

React 19 Server Components and Actions allow server data fetching and mutations directly without client-side fetching libraries in full-stack frameworks, but client state taxonomy principles remain identical for interactive UI.

localStorage access is synchronous and blocks the main thread on large payloads. Furthermore, changes to localStorage do not automatically trigger React component re-renders unless wrapped in a custom hook using useSyncExternalStore or window storage events.

Derived state is computed synchronously during render from existing props or state (e.g., filteredList = list.filter(...)) and should never be stored. Persistent state is written to browser storage and restored across sessions.