State Management Architecture
Overview of our state management approach and the golden rule for separating server and client state
State Management Architecture
Overview
This document outlines our application's state management architecture, built around the Golden Rule - our fundamental principle for state separation. This architecture optimizes for performance, maintainability, and developer experience by ensuring each type of state (server, client, and component) is handled by the tool best suited for its characteristics. By following a clear separation of concerns, we reduce complexity and improve both runtime performance and developer productivity.
Purpose & Scope
- Target Audience: React Native developers working on this application who need to understand when and how to use different state management tools
- Problems Addressed: State management complexity, prop drilling, unnecessary re-renders, and data synchronization challenges
- Scope Boundaries: Covers the three primary state management patterns and their integration, but does not cover persistence strategies or offline capabilities in depth
The Golden Rule
Server state belongs in TanStack Query, Client state belongs in Zustand, Component state belongs in React
This foundational principle guides all state management decisions in our application:
When to Apply the Golden Rule
- (Do ✅) Use TanStack Query when the data comes from an API or remote source
- (Do ✅) Use Zustand when state needs to be shared across components or persisted
- (Do ✅) Use React state when the state is only relevant to a single component
Core Components/Architecture
Component Types
| Component | Responsibility | Implementation |
|---|---|---|
| Server State | Remote data from APIs | TanStack Query |
| Client State | Application-wide UI state | Zustand |
| Component State | Local component interactions | React useState/useReducer |
When to Apply Each Component
- (Do ✅) Use TanStack Query when the data comes from an API
- (Do ✅) Use Zustand when state needs to be shared across components or persisted
- (Do ✅) Use React state when the state is only relevant to a single component
Communication Patterns
Design Principles
Core Architectural Principles
-
(Do ✅) Maintain a clear separation of concerns between server and client state
- Server state and client state have fundamentally different characteristics and should be treated differently
- Mixing concerns leads to unnecessary complexity and performance issues
-
(Do ✅) Use specialized tools optimized for each state type
- TanStack Query handles caching, invalidation, and refetching
- Zustand provides a simple API for global state with minimal boilerplate
- React state is perfect for component-level concerns
-
(Do ✅) Keep components pure and focused on rendering
- Components should primarily transform props into UI
- Delegate state management logic to hooks and stores
Trade-offs and Design Decisions
| Decision | Benefits | Trade-offs | Why We Chose It |
|---|---|---|---|
| Separate server & client state | Better performance, clearer code | Learning multiple tools | Benefits outweigh costs |
| TanStack Query for server state | Automatic caching, refetching, optimistic updates | More code than simple fetch | Drastically improves UX |
| Zustand for global state | Simple API, minimal boilerplate | Another dependency | Less complex than Redux |
| React state for component state | Built-in, familiar | No persistence | Perfect for ephemeral state |
Implementation Considerations
Performance Implications
- Query Caching: Server state is automatically cached by TanStack Query, reducing unnecessary network requests
- Zustand Selectors: Use selectors to prevent unnecessary re-renders by only subscribing to relevant slices of state
- Component Memoization: Leverage React.memo and useMemo to prevent wasteful re-renders
Scaling Considerations
- Query Client Configuration: Set up appropriate staleTime and cacheTime based on data volatility
- Store Slicing: Break down Zustand stores by domain as the application grows
- Persistence Strategy: Configure storage persistence only for critical state to avoid bloat
Related Documents
- Server State Management - Detailed guide on TanStack Query implementation
- Client State Management - Zustand patterns and best practices
- Component State Management - React state management techniques
- State Integration Patterns - How different state types work together