Claude Code and React state: the patterns to watch out for
Claude writes React that works. It also has tendencies — default patterns it reaches for that aren't always the right choice for your codebase. Here's what shows up consistently and how to handle it.
useState for everything
Claude defaults to useState for local component state. That's usually fine. The issue is when it uses useState for things that should be derived values. If you have a list and a filter, and Claude creates separate state for the filtered list — that's a derived value, not state. It causes sync bugs where the two diverge.
Review Claude's state declarations: could any of these be computed from other state instead of stored separately?
useEffect for data fetching
Claude still writes useEffect for data fetching in many cases. If you're using React Query, SWR, or another data fetching library, tell Claude explicitly. "Use React Query for all data fetching. Do not use useEffect for data fetching." Without this it will write the old pattern.
If you are using useEffect for data fetching: check the dependency array. Claude gets this wrong often — missing dependencies, or including values that change on every render and cause infinite fetches.
Context for everything global
When you ask Claude to make something accessible across components, it often reaches for Context. Context is fine for low-frequency updates (theme, locale, user session). It's wrong for high-frequency updates (form state, filter values, anything that changes on user input) because it causes full tree re-renders.
Tell Claude which global state solution you're using: Zustand, Jotai, Redux, React Query cache. It will use that pattern if you specify it.
Missing memoization, or memoization everywhere
Two failure modes: Claude writes expensive operations in render without useMemo, or Claude adds useMemo and useCallback to everything "just in case." The second one is more common with newer React.
The rule: memoization is worth it when the computation is actually expensive or when the reference stability matters (passed as a prop to a memoized child). Not as a default. Tell Claude this if it's adding memo annotations everywhere.
The state prompt that helps
Before adding any new state:
- Is this a derived value from existing state? If so, compute it instead.
- Is this global or local? If global, use [your state library].
- Does this change frequently? If yes, avoid putting it in Context.
Only create new useState if none of the above apply.
The Cursor Rules for Claude Code includes a React state rule set that guides Claude toward the right patterns for your stack. $19.