You Might Not Need State
Arguments:
- scope: what to analyze (default: your current changes). Examples: "diff to main", "PR #123", "src/components/", "whole codebase"
- fix: whether to apply fixes (default: true). Set to false to only propose changes.
User arguments: $ARGUMENTS
Context
This codebase uses React Query for all server state and Zustand for client-only global state. useState should only be used for ephemeral UI concerns (open/closed, hover, local form input). Server data should never be copied into useState or Zustand — React Query is the single source of truth.
References
Read these before analyzing:
- https://react.dev/learn/choosing-the-state-structure — 5 principles for structuring state
- https://tkdodo.eu/blog/dont-over-use-state — never store derived/computed values in state
- https://tkdodo.eu/blog/putting-props-to-use-state — never mirror props into state via useEffect
Anti-patterns to detect
- Derived state stored in useState: If a value can be computed from props, other state, or query data, compute it inline during render instead of storing it in state.
- Server state copied into useState: Never
useState+useEffectto sync React Query data into local state. Use query data directly. The only exception is forms where users edit server data. - Props mirrored into state: Never
useState(prop)+useEffect(() => setState(prop)). Use the prop directly, reset with a remountkey, or — for seed-on-transition (e.g. a modal opening) — adjust during render with theuseStateprev-tracker in.claude/rules/sim-hooks.md"State shape" (mind its sentinel-on-mount and no-useRefrules). - Chained useEffect state updates: Never chain Effects that set state to trigger other Effects. Calculate all derived values in the event handler or inline during render.
- Storing objects when an ID suffices: Store
selectedIdnot a copy of the selected object. Derive the object:items.find(i => i.id === selectedId). - State that duplicates Zustand or React Query: If the data already lives in a store or query cache, don't create a parallel useState.
Steps
- Read the references above to understand the guidelines
- Analyze the specified scope for the anti-patterns listed above
- If fix=true, apply the fixes. If fix=false, propose the fixes without applying.