Provides comprehensive state management patterns for React applications...
Patterns for managing state in React applications.
See references/infinite-cache-patterns.md for detailed infinite query cache helpers.
Is it from an API?
├─ YES → TanStack Query (server state)
└─ NO → Should it be in the URL?
├─ YES → TanStack Router search params (URL state)
└─ NO → Does it need to be global?
├─ YES → Zustand (global client state)
└─ NO → useState (local component state)
Data from APIs. Global staleTime: 0 enforces stale-while-revalidate. NEVER override per-query unless guaranteed static reference data.
Filters, pagination, search, tabs — anything shareable via URL. Use useTableUrlState.
UI state: modals, dropdowns, form inputs. Use useState.
Truly global: auth user, theme, sidebar state. Minimal usage.
Store only IDs in local state; derive full objects from server state. Prevents stale references after background refetches.
When showing different items (e.g., detail sheet), key state by item ID and derive "current" inline — never use reset effects.
Date.now() and Math.random() are impure. Use useState(() => Date.now()) lazy initializer, not useMemo.
Keep interval-driven state in the smallest component subtree that needs it. Avoid minute/second timers in route containers.
On unmount, compact to page 1 so remount triggers single revalidation.
After mutation: setQueriesData for active queries (immediate), invalidateQueries for inactive (background).
Pure utility functions: upsertItemInPages, removeItemFromPages, compactToFirstPage. Place in features/{feature}/lib/cache-helpers.ts.
useState