useState, useEffect, and related hooks that lead to bugs, performance issues, or unnecessary re-renders.
Rules
no-derived-state-effect
no-derived-state-effect
Severity: error
Rule ID:Good:Or use a key to reset component state:
Rule ID:
react-doctor/no-derived-state-effectDetects state that is derived from props or other state inside useEffect. This pattern is almost always wrong.Why it’s bad:- Creates an extra render cycle
- State updates happen after render instead of during
- Can cause infinite loops if dependencies aren’t perfect
no-fetch-in-effect
no-fetch-in-effect
Severity: error
Rule ID:Good:
Rule ID:
react-doctor/no-fetch-in-effectPrevents using fetch() directly inside useEffect. Manual data fetching leads to race conditions, missing loading states, and no caching.Why it’s bad:- Race conditions when component unmounts
- No automatic deduplication or caching
- Missing loading/error states
- Waterfall requests
no-cascading-set-state
no-cascading-set-state
Severity: warn
Rule ID:Good:
Rule ID:
react-doctor/no-cascading-set-stateFlags useEffect containing 3 or more setState calls. This indicates state that should be managed together.Why it’s bad:- Multiple setState calls = multiple re-renders
- Hard to keep state synchronized
- Suggests missing abstraction
no-effect-event-handler
no-effect-event-handler
Severity: warn
Rule ID:Good:
Rule ID:
react-doctor/no-effect-event-handlerDetects useEffect that runs only when a specific value changes and contains a single if statement. This is usually an event handler in disguise.Bad:no-derived-useState
no-derived-useState
Severity: warn
Rule ID:Good:
Rule ID:
react-doctor/no-derived-useStateCatches useState initialized directly from a prop value. If the prop changes, state won’t update.Bad:prefer-useReducer
prefer-useReducer
Severity: warn
Rule ID:Good:
Rule ID:
react-doctor/prefer-useReducerSuggests using useReducer when a component has 5+ useState calls for related state.Bad:rerender-lazy-state-init
rerender-lazy-state-init
Severity: warn
Rule ID:Good:
Rule ID:
react-doctor/rerender-lazy-state-initEnforces lazy initialization for useState when initialized with a function call. The function runs on every render even though only the first result is used.Bad:rerender-functional-setstate
rerender-functional-setstate
Severity: warn
Rule ID:Good:
Rule ID:
react-doctor/rerender-functional-setstateRequires using functional updates when the new state depends on the old state to avoid stale closures.Bad:rerender-dependencies
rerender-dependencies
Severity: error
Rule ID:Good:
Rule ID:
react-doctor/rerender-dependenciesCatches object literals and array literals in dependency arrays. These create new references every render, causing the effect to run infinitely.Bad:Related Rules
- Performance Rules - Rendering optimization rules
- Architecture Rules - Component structure rules