← Back to all products
$29
State Management Patterns
Zustand, Jotai, and React Query patterns for complex state: optimistic updates, caching, and real-time sync.
JSONMarkdownTypeScriptReact
📄 Product Preview
Try the interactive reader and demo tools below, or get the full product with all content unlocked.
📖 Interactive Reader (Free Preview) ⚙ Try Demo Tools 📦 Download Free Sample📁 File Structure 25 files
state-management-patterns/
├── LICENSE
├── README.md
├── examples/
│ ├── dashboard-jotai.tsx
│ ├── data-table-react-query.tsx
│ └── todo-app-zustand.tsx
├── free-sample.zip
├── guide/
│ └── decision-guide.md
├── guides/
│ └── decision-guide.md
├── index.html
├── src/
│ ├── jotai/
│ │ ├── async-atoms.ts
│ │ ├── atom-families.ts
│ │ └── atoms.ts
│ ├── react-query/
│ │ ├── cache-invalidation.ts
│ │ ├── infinite-queries.ts
│ │ ├── mutations.ts
│ │ └── queries.ts
│ ├── realtime/
│ │ ├── optimistic-updates.ts
│ │ └── websocket-sync.ts
│ └── zustand/
│ ├── middleware.ts
│ ├── persistence.ts
│ └── store-slices.ts
├── tests/
│ ├── jotai.test.ts
│ ├── react-query.test.ts
│ └── zustand.test.ts
└── tsconfig.json
📖 Documentation Preview README excerpt
State Management Patterns
Battle-tested patterns for managing complex client state in React applications using Zustand, Jotai, and React Query. This collection covers the patterns that emerge when you move beyond simple useState — optimistic updates, cache synchronization, real-time data, and the hard decisions about where state actually belongs.
What's Inside
Zustand Patterns (`src/zustand/`)
- Store Slices — Split large stores into composable slices that share a single store instance. Includes typed slice creators and cross-slice communication.
- Middleware Stack — Logging, devtools integration, performance tracking, and immer middleware composed together.
- Persistence Layer — Storage adapters (localStorage, sessionStorage, IndexedDB) with migration support for evolving store shapes.
Jotai Patterns (`src/jotai/`)
- Atoms & Derived Atoms — Primitive atoms, computed atoms with selectors, and write-only atoms for complex updates.
- Async Atoms — Data fetching atoms with loading/error states, retry logic, and Suspense integration.
- Atom Families — Parameterized atoms for managing collections (e.g., per-item expanded state, per-tab filters).
React Query Patterns (`src/react-query/`)
- Query Patterns — Dependent queries, parallel queries, conditional fetching, and placeholder/initial data strategies.
- Mutations & Optimistic Updates — Mutation patterns with rollback, optimistic list updates, and toast notifications on failure.
- Infinite Queries — Cursor-based and offset-based infinite scroll with bi-directional support.
- Cache Invalidation — Granular invalidation, cache seeding from mutations, and stale-while-revalidate strategies.
Real-Time Sync (`src/realtime/`)
- WebSocket Integration — Reconnecting WebSocket manager that syncs server events into Zustand and React Query caches.
- Optimistic Updates — Shared patterns for optimistic UI across all three libraries, with server reconciliation.
Decision Guide (`guides/decision-guide.md`)
When should you reach for Zustand vs. Jotai vs. React Query? A decision tree based on the _shape_ of your state problem, not library popularity.
Working Examples (`examples/`)
- Todo app with Zustand (local-first with sync)
- Dashboard with Jotai (fine-grained reactivity)
- Data table with React Query (server state with filtering)
Quick Start
# Install the libraries you want to use (pick one or combine):
npm install zustand immer
npm install jotai
npm install @tanstack/react-query
# Copy the patterns you need into your project
cp -r src/zustand/ your-project/src/state/
Each pattern file is self-contained. Import what you need, ignore the rest.
File Structure
state-management-patterns/
├── README.md
├── LICENSE
├── tsconfig.json
├── src/
│ ├── zustand/
│ │ ├── store-slices.ts # Composable store slices
│ │ ├── middleware.ts # Custom middleware stack
│ │ └── persistence.ts # Storage adapters & migrations
*... continues with setup instructions, usage examples, and more.*
📄 Code Sample .tsx preview
examples/dashboard-jotai.tsx// ============================================================================
// Example: Dashboard with Jotai (Fine-Grained Reactivity)
// ============================================================================
//
// A dashboard that shows why Jotai excels at fine-grained updates.
// Each widget subscribes to only the atoms it needs, so updating one
// metric doesn't re-render the entire dashboard.
//
// ============================================================================
import React, { useEffect } from "react";
import { atom, useAtom, useAtomValue, useSetAtom } from "jotai";
import { atomWithStorage } from "jotai/utils";
// ---------------------------------------------------------------------------
// Dashboard atoms — each metric is an independent atom
// ---------------------------------------------------------------------------
// Individual metrics — updating revenue doesn't re-render the users widget
const revenueAtom = atom<number>(0);
const activeUsersAtom = atom<number>(0);
const conversionRateAtom = atom<number>(0);
const errorRateAtom = atom<number>(0);
// Historical data for sparkline charts
const revenueHistoryAtom = atom<number[]>([]);
const usersHistoryAtom = atom<number[]>([]);
// Dashboard settings — persisted to localStorage
const refreshIntervalAtom = atomWithStorage<number>("dashboard-refresh", 5000);
const dashboardLayoutAtom = atomWithStorage<"grid" | "list">("dashboard-layout", "grid");
// Derived atoms — computed from individual metrics
const healthScoreAtom = atom<number>((get) => {
const errorRate = get(errorRateAtom);
const conversion = get(conversionRateAtom);
// Health score: 100 = perfect, decreases with errors, increases with conversion
return Math.max(0, Math.min(100, Math.round(100 - errorRate * 10 + conversion)));
});