Skip to main content

State Management, Data Fetching & Caching

SECTION 1 — THE REAL PROBLEM: TOO MUCH STATE

State is the hardest problem in frontend engineering.

Why?

  • state changes over time

  • state comes from many sources

  • state can be stale

  • state can be duplicated

  • state can conflict

Average engineers add state until things “work”.

Elite engineers remove state until correctness remains.


SECTION 2 — THE 4 TYPES OF FRONTEND STATE

Elite engineers classify state explicitly.

1️⃣ UI State

Examples:

  • modal open/closed

  • selected tab

  • dropdown expanded

  • loading spinner visible

Characteristics:

  • local

  • ephemeral

  • resets easily

👉 Keep this local to components.


2️⃣ Client State

Examples:

  • form input values

  • wizard progress

  • temporary drafts

Characteristics:

  • user-owned

  • often mutable

  • sometimes persisted

👉 Use local state or scoped stores.


3️⃣ Server State

Examples:

  • user profile

  • application data

  • lists, feeds

  • permissions

Characteristics:

  • source of truth is backend

  • async

  • cacheable

  • can be stale

👉 Never manage this manually.


4️⃣ Derived State

Examples:

  • computed totals

  • filtered lists

  • validation flags

Characteristics:

  • should be derived, not stored

👉 If you store derived state, bugs multiply.


Elite Rule

If state can be derived, don’t store it.


SECTION 3 — SERVER STATE IS NOT CLIENT STATE

This is one of the most important frontend insights.

Server state:

  • comes from APIs

  • can be refetched

  • can be invalidated

  • can be cached

  • can be stale

Treating server state like local state causes:

  • race conditions

  • stale UIs

  • duplicate logic

  • massive complexity


Correct Approach

Use a server-state library (React Query / TanStack Query / SWR).

They handle:

  • caching

  • refetching

  • deduplication

  • retries

  • background refresh

  • stale data

Elite engineers delegate server state management.


SECTION 4 — DATA FETCHING AS A STATE MACHINE

Every API call has states:

idle → loading → success
↘ error ↗ retry

Elite engineers model this explicitly.

They do not:

  • guess loading states

  • mix multiple requests blindly

  • assume order of arrival


Race Condition Example

User types fast → multiple requests fire → responses return out of order.

Elite solutions:

  • cancel previous requests

  • ignore stale responses

  • use query keys correctly


SECTION 5 — CACHING IN FRONTEND SYSTEMS

Caching is not optional.

Without caching:

  • UIs flicker

  • network usage explodes

  • performance feels bad


What Frontend Should Cache

  • server state

  • lists

  • read-heavy data

  • reference data


Cache Invalidation (Frontend Reality)

Cache invalidation happens when:

  • mutation succeeds

  • user logs out

  • context changes (org, account)

  • time-based staleness

Elite engineers think:

“What must be invalidated when this changes?”


Elite Rule

Stale data is better than broken UI.


SECTION 6 — MUTATIONS & OPTIMISTIC UPDATES

Mutations change server state.

They introduce complexity:

  • latency

  • failure

  • retries

  • UI consistency


Optimistic Update Model

  1. Update UI immediately

  2. Send request

  3. If success → keep

  4. If failure → rollback

Used for:

  • likes

  • toggles

  • reordering

  • quick feedback actions


Elite Rule

Optimistic updates require easy rollback.

If rollback is complex → don’t do optimistic updates.


SECTION 7 — PREVENTING FRONTEND RACE CONDITIONS

Race conditions happen when:

  • multiple requests overlap

  • state updates interleave

  • async effects collide

Elite prevention techniques:

  • request cancellation

  • versioning requests

  • scoping effects

  • avoiding shared mutable state


Example Technique

Store a request ID and only apply the latest response.


SECTION 8 — ERROR HANDLING AS A UX FEATURE

Errors are not edge cases.

They are part of normal operation.


Elite Error UX

  • visible but calm

  • actionable

  • retryable

  • non-destructive

Never:

  • crash entire app

  • show raw error text

  • hide failures silently


Error Boundaries

Elite engineers:

  • isolate failure

  • prevent cascade

  • show fallbacks


SECTION 9 — FORMS: THE HARDEST FRONTEND PROBLEM

Forms combine:

  • client state

  • validation

  • async calls

  • error handling

  • accessibility

Elite form principles:

  • validate early

  • validate often

  • separate UI vs validation logic

  • treat submission as a workflow


Form State Machine

editing → validating → submitting → success
↘ error ↗ retry

Same pattern as backend workflows — just smaller.


SECTION 10 — COMMON STATE MANAGEMENT TRAPS

❌ Global store for everything

❌ Storing derived state

❌ Manual server state handling

❌ Mixing UI and business logic

❌ Multiple sources of truth

❌ Over-fetching

Elite engineers actively remove these.


SECTION 11 — HOW ELITE FRONTEND ENGINEERS WORK

They:

  • sketch state diagrams before coding

  • choose minimal state

  • separate concerns ruthlessly

  • let libraries handle hard problems

  • test failure paths

  • optimize for clarity over cleverness


SECTION 12 — SIGNALS YOU’VE MASTERED STATE & DATA

You know you’re there when:

  • your UIs rarely desync

  • loading/error states feel natural

  • bugs reduce dramatically

  • code becomes simpler over time

  • new features don’t destabilize old ones