.agents/skills/refactor-react-effects/SKILL.md
Do not add useEffect by default. Use it only to synchronize a component with
a concrete system outside React. If there is no external system, remove the
effect.
Before adding or retaining an effect, answer all of these questions:
If the first question has no concrete answer, do not use an effect.
web/AGENTS.md and the nearest package guidance before changing web
code.../frontend-large-feature-architecture/SKILL.md.references/refactoring-patterns.md
before implementing a refactor.Apply these rules in order:
useState initializer.key to remount for a new entity
only when discarding the old local draft is intended. Use an explicit user
action for refresh/reset when drafts must not be overwritten silently.actions/*.ts, or store
actions. Pass a React Query client, mutation callback, or vanilla Zustand
store as a dependency; never call React hooks from those actions.useEffect.Presume that an effect which writes React or Zustand state from props or query
data is removable. Do not evade the design problem by switching to
useLayoutEffect, suppressing dependency lint, hiding the same synchronization
in a custom hook, or adding an ESLint disable.
Refactor when any of these shapes appear:
useEffect(() => setX(deriveFromY(y)), [y]);setState;Identify the state owner, query owner, user events, external systems, and loading/error states. For a bug fix, add the failing test first and confirm it fails. For a behavior-preserving migration, reuse existing coverage where it protects the relevant behavior; add focused coverage only for a meaningful behavior risk such as draft preservation, entity changes, refetches, submits, or cleanup. Do not add tests that inspect source code or merely assert that a hook is absent. Use behavior tests and the effect inventory instead.
Search the full target module, including tests and stories:
rg -n '\b(use(?:Layout)?Effect|React\.use(?:Layout)?Effect)\b' 'web/src/features/<feature>'
Classify every result as:
Do not refactor from a raw count alone. Record what triggers each effect, what it writes or controls, and the replacement pattern.
Prefer this order:
Keep user-visible behavior stable. Avoid bundling unrelated file moves, visual changes, and state architecture changes into the same slice.
Repeat the inventory after each slice. Before declaring a submodule clean:
Do not add or modify effect-specific ESLint rules or pre-commit checks as part of this workflow. Treat enforcement policy as separate, explicitly requested work.
Run, at minimum:
pnpm --filter web run lint;Report the exact command summary lines and any retained effects with their external-system rationale.
Return valid Markdown. For module audits, include a compact table with the effect location, classification, replacement, and status. Check headings, lists, links, tables, backticks, and code fences for valid Markdown syntax before returning the report.