Back
Web Fundamentals

State Management: Choosing the Right Solution

Web Fundamentals
Build & Deployment: Monorepo, CI/CD, Strategies & Release SafetyState Management: Choosing the Right SolutionRedux: Predictable State Container (RTK + RTK Query)React Query (TanStack Query): Server State CachingData Fetching Patterns: REST, GraphQL, tRPC & Real-timeGraphQL Fundamentals for Frontend: Shape, Caching, and TradeoffsgRPC-Web Fundamentals: Browser Constraints and Proxy ModelCaching Strategies: Client, Server & EdgeData Normalization: Organizing State for PerformanceAPI Design Best Practices: Pagination, Errors, Versioning & Type SafetyAPI Versioning Strategies for Frontend CompatibilityPagination: Offset vs Cursor-BasedRate Limiting & API Resilience: Retries, Backoff, Jitter, IdempotencyHow Frontend Developers Can Handle Millions of API Requests Without Crashing EverythingBrowser Storage: Cookies, SessionStorage, LocalStorage, IndexedDBReal-time Communication: WebSockets, SSE & PollingWebRTC: Real-Time Communication in the BrowserCore Web Vitals: LCP, INP & CLSPerformance Optimization Trade-offsCritical Resource Prioritization: Optimize Loading OrderCode Splitting: Optimize Bundle Size with Dynamic ImportsTree Shaking: Eliminate Dead Code from Your BundleLazy Loading: Load Resources On-DemandResource Hints: Preload, Prefetch & PreconnectText Compression: Gzip and BrotliImage & Video Optimization: Modern Formats & TechniquesAdaptive Loading: Optimize for Device & NetworkList Virtualization: Render Large Lists EfficientlyWeb Workers vs Main Thread: Offloading Heavy WorkMemory Leaks in Frontend Apps: Detection & PreventionManaging Third-Party Scripts: Optimization StrategiesHow CDNs Work: Edge Delivery, Caching & PerformanceHTTP Caching Deep Dive: Cache-Control, ETag & RevalidationService Workers & Offline Strategy: Cache First, Network First & Update LifecyclePWA Fundamentals: Manifest, Installability & Offline UXCritical Rendering PathScript Loading: async vs deferEvent Loop: Understanding JavaScript Execution ModelJavaScript Module Systems: CJS vs ESM vs UMDDynamic Module Loading: import() FunctionImport on Interaction: Load When User InteractsImport on Visibility: Lazy Loading with IntersectionObserverBrowser Rendering Pipeline & Layout ThrashingRendering Strategies: CSR vs SSR vs SSG vs ISRStreaming SSR: Progressive HTML StreamingIslands Architecture: Independent Component HydrationReact Server Components: Zero-JS Server RenderingFramework Reactivity: React, Vue, Svelte & SolidHTTP/1.1 vs HTTP/2 vs HTTP/3 (QUIC) for Frontend PerformanceDNS Resolution: Path, TTL, Caching & Frontend ImpactCross-Site Scripting (XSS) AttacksCross-Site Request Forgery (CSRF) AttacksCORS Explained: Cross-Origin Resource SharingCORS Preflight in Practice: Credentials, Simple Requests & MisconfigurationsContent Security Policy (CSP)Why is HTTPS Secure? Understanding TLS/SSLAuthorization Best PracticesCookie Security & Session Hardening: SameSite, HttpOnly, Secure
mediumFrontend Architecture

State Management: Choosing the Right Solution

TL;DRServer state (API data) → React Query. Client state (UI) → Zustand/Context. Redux for complex workflows.
Very High Signal
Google
Meta
Netflix
Agoda
30-Second Answerstart every interview with this

The best state management solution depends on what kind of state you're handling. Separate server state (fetched data that can go stale) from client state (UI-owned data). React Query owns server state. Zustand or Context handles most client state. Redux shines for large, complex apps with heavy workflows.

Server state is rented furniture — it can change when the owner (API) updates it, so you need smart caching and synchronization (React Query). Client state is your own furniture — you fully control it and just need a good place to keep it organized (Zustand/Context). Redux is a big, formal living room for when you have many pieces and many people moving them around.

Server State (API Data)
React Query (caching, refetch, invalidation)
Client State (UI)
Zustand / Context / Redux

1React Context

Built-in solution for low-frequency global state like theme, auth status, or locale. Simple but can cause broad rerenders if overused for high-churn data.

2Zustand

Lightweight, minimal-boilerplate client store with excellent selector-based subscriptions. Ideal for most UI state (filters, modals, forms).

3Redux Toolkit

Structured patterns, powerful DevTools, and middleware. Best for large teams and complex app logic.

4React Query (TanStack Query)

The standard for server state. Handles caching, background refetch, mutations, and optimistic updates automatically.

PropertyContextZustandRedux ToolkitReact Query
Best ForLow-frequency global configMost client UI stateLarge/complex appsServer/API data
ComplexityLowVery lowMedium-HighLow-Medium
PerformanceRisky for high-churn stateExcellent with selectorsExcellent with disciplineExcellent caching

Context

Best For

Low-frequency global config

Complexity

Low

Performance

Risky for high-churn state

Zustand

Best For

Most client UI state

Complexity

Very low

Performance

Excellent with selectors

Redux Toolkit

Best For

Large/complex apps

Complexity

Medium-High

Performance

Excellent with discipline

React Query

Best For

Server/API data

Complexity

Low-Medium

Performance

Excellent caching

Common questions

  • ›“How do you choose between Context, Zustand, Redux, and React Query?”
  • ›“When would you use React Query vs Zustand?”
  • ›“Why is Redux still relevant in 2026?”
  • ›“How do you avoid unnecessary rerenders in state management?”

What interviewers look for

  • Clear separation of server vs client state
  • Practical trade-off reasoning (boilerplate vs performance vs team scale)
  • Understanding of rerender control and selectors
  • Modern default recommendation (React Query + Zustand)

Short answer (60 sec)

Use React Query for server/API state and Zustand (or Context) for client/UI state. Choose Redux Toolkit only when you need strong structure, middleware, or large-team consistency.

Detailed answer (senior level)

Separate concerns first: React Query owns server state (caching, refetch, mutations). For client state, Context works for simple global config, Zustand for most UI needs with minimal boilerplate, and Redux Toolkit for complex workflows or large teams. The real skill is avoiding duplication and unnecessary rerenders through proper selectors and boundaries.

  • Putting server data into Zustand/Redux instead of using React Query
  • Using Context for high-frequency state (causes rerenders)
  • Overusing Redux for simple apps (unnecessary boilerplate)
  • Not using selectors in Zustand/Redux
  • Treating all state the same way
Key Takeaways
  • ✓Separate server state (React Query) from client state
  • ✓Context for simple global config
  • ✓Zustand for most client/UI state (lightweight & fast)
  • ✓Redux Toolkit for complex apps and large teams
  • ✓Use selectors to prevent unnecessary rerenders
  • ✓Default modern stack: React Query + Zustand
  • ✓Measure rerenders and bundle impact — don’t follow trends blindly
Previous TopicBuild & Deployment: Monorepo, CI/CD, Strategies & Release SafetyNext Topic Redux: Predictable State Container (RTK + RTK Query)

On this page