State Management, Data Fetching & Caching
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.
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.
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.
DATA FETCHING AS A STATE MACHINE
Every API call has states:
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
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.
MUTATIONS & OPTIMISTIC UPDATES
Mutations change server state.
They introduce complexity:
-
latency
-
failure
-
retries
-
UI consistency
Optimistic Update Model
-
Update UI immediately
-
Send request
-
If success → keep
-
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.
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.
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
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
Same pattern as backend workflows — just smaller.
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.
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
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