New
Introducing React Doctor for Enterprise

react-hooks-js/set-state-in-render

Validates against setting state during render, which can trigger additional renders and potential infinite render loops

Validation prompt

Use this to decide whether a fired diagnostic is real or a false positive.

Fires on UNCONDITIONAL setState during render — guaranteed infinite loop. The conditional sync-state-to-prop pattern (if (items !== prevItems) { setPrevItems(items); setSelection(null); }) is explicitly allowed and is the documented escape hatch. False positive: rare; bare setState in the component body is almost always a real bug.

Fix prompt

Use this once validation confirms the diagnostic is real.

Move the setState into an event handler (onClick, onChange, onSubmit) or into useEffect if it must run after commit. To synchronize state with a prop change across renders, use the gated pattern above — store the previous prop in state and only call setState when it differs. For clamping or derived values, derive during render instead of mirroring into state. See https://react.dev/reference/eslint-plugin-react-hooks/lints/set-state-in-render

More React Compiler rules from the rules reference:

  • react-hooks-js/static-components: Validates that components are static, not recreated every render. Components that are recreated dynamically can reset state and trigger excessive re-rendering
  • react-hooks-js/todo: Unimplemented features
  • react-hooks-js/unsupported-syntax: Validates against syntax that we do not plan to support in React Compiler
  • react-hooks-js/use-memo: Validates usage of the useMemo() hook against common mistakes. See [`useMemo()` docs](https://react.dev/reference/react/useMemo) for more information.
  • react-hooks-js/void-use-memo: Validates that useMemos always return a value and that the result of the useMemo is used by the component/hook. See [`useMemo()` docs](https://react.dev/reference/react/useMemo) for more information.