state-management · git:20261026.8145f4e · 2026-10-26 · sha256 16a01c0c8761b30c
state-management git:20261026.8145f4eA
Immutable. This exact content never changes and is served at /api/v1/blob/16a01c0c8761b30c.
---
name: state-management
description: Declarative state machines, TanStack Query server-state caching, invalidation, optimistic updates, atomic Zustand slices, and signals.
---
# Declarative State Machines, Cache & Signals (`/state-management`)
> **Philosophy**: *Server state is an asynchronous remote cache; client state is an ephemeral synchronous state machine. Never store remote data in local UI state. Prohibit boolean explosion. Invalidate with Query Key Factories. Memoize store selectors to eliminate re-render cascades.*
This skill establishes production architecture for state management across **TanStack Query (React Query)**, **Zustand**, **Jotai**, **XState**, and **Signals**.
---
## 1. The Core State Architecture Gates
```mermaid
flowchart TD
A["User Interaction / Data Fetch"] --> B["Gate 1: State Separation (Server Cache vs Client State)"]
B --> C["Gate 2: Finite State Machine (idle | loading | success | error)"]
C --> D["Gate 3: Query Key Factory (Hierarchical Cache Invalidation)"]
D --> E["Gate 4: Selector Memoization (Granular Store Subscriptions)"]
E --> F["Gate 5: Optimistic Updates & Rollback Safety"]
```
1. **Gate 1: Strict Boundary Separation**: Server state (remote API data) belongs exclusively in TanStack Query. Ephemeral client state (drawer open/closed, form draft) belongs in local state or Zustand.
2. **Gate 2: Zero Boolean Explosion**: Replace uncoordinated flags (`isLoading`, `isError`, `isSuccess`) with a single deterministic state machine enum (`status: 'idle' | 'loading' | 'success' | 'error'`).
3. **Gate 3: Query Key Factories**: Centralize query keys into structured, strongly-typed factory objects (`projectKeys.detail(id)`) for deterministic cache invalidation.
4. **Gate 4: Granular Store Subscriptions**: Always select specific slices (`useStore(state => state.isOpen)`). Never subscribe to the root store object.
5. **Gate 5: Optimistic Mutations with Rollbacks**: Optimistic UI updates must snapshot previous cache state in `onMutate` and roll back on `onError`.
---
## 2. Query Key Factory & TanStack Query (TypeScript)
```typescript
// features/projects/queries/projectKeys.ts
export const projectKeys = {
all: ["projects"] as const,
lists: () => [...projectKeys.all, "list"] as const,
list: (filters: Record<string, unknown>) => [...projectKeys.lists(), filters] as const,
details: () => [...projectKeys.all, "detail"] as const,
detail: (id: string) => [...projectKeys.details(), id] as const
};
// Optimistic mutation hook
export function useUpdateProjectTitle() {
const queryClient = useQueryClient();
return useMutation({
mutationFn: ({ id, title }: { id: string; title: string }) => api.updateTitle(id, title),
onMutate: async ({ id, title }) => {
await queryClient.cancelQueries({ queryKey: projectKeys.detail(id) });
const previous = queryClient.getQueryData<Project>(projectKeys.detail(id));
queryClient.setQueryData<Project>(projectKeys.detail(id), (old) =>
old ? { ...old, title } : undefined
);
return { previous };
},
onError: (_err, { id }, context) => {
if (context?.previous) {
queryClient.setQueryData(projectKeys.detail(id), context.previous);
}
},
onSettled: (_data, _err, { id }) => {
queryClient.invalidateQueries({ queryKey: projectKeys.detail(id) });
}
});
}
```
---
## 3. Atomic Zustand Slice with Selector Memoization
```typescript
import { create } from "zustand";
interface WorkspaceState {
isSidebarOpen: boolean;
activeFilter: string;
toggleSidebar: () => void;
setActiveFilter: (filter: string) => void;
}
export const useWorkspaceStore = create<WorkspaceState>((set) => ({
isSidebarOpen: true,
activeFilter: "all",
toggleSidebar: () => set((state) => ({ isSidebarOpen: !state.isSidebarOpen })),
setActiveFilter: (activeFilter) => set({ activeFilter })
}));
// ✅ DEFENSIVE: Granular memoized selector prevents re-rendering on unrelated state changes
export function useSidebarOpen(): boolean {
return useWorkspaceStore((state) => state.isSidebarOpen);
}
```
---
## 4. State Management Verification CLI
Audit your codebase for boolean explosions and un-memoized store subscriptions:
```bash
python3 skills/state-management/scripts/verify_state_hygiene.py --path . --strict
```
Audited Rules:
- `STATE-BOOLEAN-EXPLOSION`: Flags components using multiple simultaneous boolean status flags.
- `STATE-UNMEMOIZED-STORE-SUBSCRIPTION`: Flags consuming an entire Zustand/Redux store without a selector.
- `STATE-RAW-STRING-QUERY-KEY`: Flags raw un-namespaced query key strings in `useQuery`.