Skip to content

React Doctor

492 rules react-doctor@0.9.14

Complete effective rule inventory.

Docs

Rules

40 rules on this page · 492 total

  • react-doctor/no-assertive-status

    Keep role="status" polite. Use role="alert" only when an interruption is genuinely imperative.

    : warning in React projects
    No autofix
  • react-doctor/no-async-effect-callback

    Don't make the effect callback async. Define an async function inside the effect and call it, then return a real cleanup function if you need one.

    : warning in React projects
    No autofix
  • react-doctor/no-async-event-handler-without-reentry-guard

    An async onClick/onSubmit handler on a host control that awaits a mutating request and sets state only afterward stays interactive across the await, so a double-click fires the write twice. Add a leading if (busy) return guard, or set a flag before the await inside try and reset it in finally while the control is disabled.

    : warning in React projects
    No autofix
  • react-doctor/no-autofocus

    Do not use autoFocus. It disorients users on load.

    : warning in React projects
    No autofix
  • react-doctor/no-autoplay-without-muted

    Always pair autoPlay with muted (and playsInline): <video autoPlay muted loop playsInline />. If the sound matters, drop autoPlay and let users start it.

    : warning in React projects
    No autofix
  • react-doctor/no-blocked-paste

    Allow paste so people can use password managers, verification codes, assistive tools, and copied text without retyping it.

    : error in React projects
    No autofix
  • react-doctor/no-collapsed-literal-or-chain-as-value

    Compare against each value separately (or use an array .includes(x)) instead of an all-literal ||/&& chain, which short-circuits to its first literal and drops the rest.

    : warning in React projects
    No autofix
  • react-doctor/no-conflicting-spring-options

    Choose either stiffness/damping/mass or duration/bounce for a Motion spring so every configured value takes effect.

    : warning in React projects
    No autofix
  • react-doctor/no-controlled-input-value-without-state-update

    Drive the input's value from state (const [value, setValue] = useState(...)) that onChange updates, or drop value if the field is meant to be read-only.

    : warning in React projects
    No autofix
  • react-doctor/no-create-context-in-render

    Move createContext(...) outside the component, to the top level of the file, so it stays the same on every render.

    : error in React projects
    No autofix
  • react-doctor/no-create-object-url-in-render

    Create object URLs in an effect or event handler and revoke each URL when it is replaced or no longer needed.

    : warning in React projects
    No autofix
  • react-doctor/no-create-ref-in-function-component

    Replace createRef() with the useRef() hook inside function components and hooks. createRef is only for class components.

    : warning in React projects
    No autofix
  • react-doctor/no-create-store-in-render

    Create stores at module scope so subscribers are not cut off and saved state does not reset every render.

    : error in React projects
    No autofix
  • react-doctor/no-danger-with-children

    Use either children or dangerouslySetInnerHTML so React does not ignore one source of content.

    : error in React projects
    No autofix
  • react-doctor/no-deprecated-keyboard-event-keycode-which

    KeyboardEvent.keyCode/which/charCode are deprecated and layout/engine dependent for character keys. Branch on event.key (logical key like '/') or event.code (physical position) so the handler works across keyboard layouts and browsers.

    : warning in React projects
    No autofix
  • react-doctor/no-did-mount-set-state

    Setting state in componentDidMount triggers an extra render. Use getDerivedStateFromProps or initial state instead.

    : warning in React projects
    No autofix
  • react-doctor/no-did-update-set-state

    Setting state in componentDidUpdate causes another render and can loop. Use getDerivedStateFromProps instead.

    : warning in React projects
    No autofix
  • react-doctor/no-direct-mutation-state

    Don't change this.state by hand. setState() overwrites it anyway, so always go through setState().

    : error in React projects
    No autofix
  • react-doctor/no-direct-state-mutation

    Call the setter with a brand new value instead: setItems([...items, newItem]), setItems(items.filter(x => x !== target)), or setItems(items.toSorted(...)). React only redraws when the value is new, so changing it in place does nothing.

    : warning in React projects
    No autofix
  • react-doctor/no-distracting-elements

    Replace <marquee> and <blink> with normal markup so motion does not distract or disorient users.

    : error in React projects
    No autofix
  • react-doctor/no-document-write

    Don't use document.write()/document.writeln(). Append DOM nodes or set innerHTML/textContent on a specific element instead.

    : warning in React projects
    No autofix
  • react-doctor/no-effect-with-fresh-deps

    Move the value inside the hook body and depend on its simple inputs instead, or wrap it in useMemo / useCallback so it stays the same between renders.

    : error in React projects
    No autofix
  • react-doctor/no-effect-wrapper-discards-callback-cleanup-return

    A custom effect wrapper must return its forwarded EffectCallback's result so React can run the cleanup. Calling it as a bare fn() instead of return fn() silently drops the cleanup, leaking every subscription/timer/listener it set up.

    : warning in React projects
    No autofix
  • react-doctor/no-enter-submit-without-ime-composition-guard

    Bail on IME composition before acting on Enter: if (e.nativeEvent.isComposing) return; (or track composition with onCompositionStart/onCompositionEnd). Otherwise Enter fires mid-composition and commits a half-typed value for CJK users.

    : warning in React projects
    No autofix
  • react-doctor/no-eval

    Use JSON.parse for data, or rewrite the code so it doesn't build and run code from strings.

    : error in React projects
    No autofix
  • react-doctor/no-fetch-in-effect

    Use a data-fetching layer or Server Component so fetches do not race, double-fire, or leak from useEffect.

    : warning in React projects
    No autofix
  • react-doctor/no-fill-map-element-as-key

    After .fill(value) every element is identical, so a lone .map((n) => ...) binds n to that value (whatever the parameter is named) and gives every child the same key. Add the index as the second parameter: .map((_, index) => ...).

    : warning in React projects
    No autofix
  • react-doctor/no-find-dom-node

    Use a ref to reach DOM nodes because findDOMNode was removed in React 19 and can crash the app.

    : warning in React projects
    No autofix
  • react-doctor/no-floating-then-in-jsx-handler

    A .then() chain with no .catch in an event handler becomes an uncaught promise rejection no error boundary can catch; add a .catch handler (or make the handler async and try/catch).

    : warning in React projects
    No autofix
  • react-doctor/no-focusable-content-in-aria-hidden

    Remove focusable descendants from aria-hidden content, or hide and disable the whole subtree together.

    : warning in React projects
    No autofix
  • react-doctor/no-hydration-branch-on-browser-global

    Render the same initial output on the server and client, then switch after mount or use useSyncExternalStore with a stable server snapshot.

    : error in React projects
    No autofix
  • react-doctor/no-img-lazy-with-high-fetchpriority

    Don't combine loading="lazy" with fetchPriority="high". A high-priority image (usually the LCP) should load eagerly; a lazy image is by definition not high priority.

    : warning in React projects
    No autofix
  • react-doctor/no-impure-state-updater

    Keep state updater callbacks pure and return only the next state. Move notifications, storage, timers, ref writes, and other external work into the event or effect that queues the update.

    : error in React projects
    No autofix
  • react-doctor/no-indeterminate-attribute

    Assign the checkbox element's indeterminate DOM property, usually through a ref, because the HTML attribute does not control its visual state.

    : warning in React projects
    No autofix
  • react-doctor/no-interactive-element-to-noninteractive-role

    Do not give an interactive element a role that says it is not interactive.

    : warning in React projects
    No autofix
  • react-doctor/no-invalid-progress-range

    Keep determinate progress values within a valid positive range so visual and assistive feedback report the same advancement.

    : error in React projects
    No autofix
  • react-doctor/no-is-mounted

    isMounted doesn't work in modern React. Track mount state with a ref, or cancel the async work instead.

    : warning in React projects
    No autofix
  • react-doctor/no-json-parse-stringify-clone

    Replace JSON.parse(JSON.stringify(value)) with structuredClone(value). It is faster and preserves Dates, Maps, Sets, and cyclic references.

    : warning in React projects
    No autofix
  • react-doctor/no-legacy-class-lifecycles

    Move componentWillMount work to componentDidMount, componentWillReceiveProps to componentDidUpdate or the static getDerivedStateFromProps, and componentWillUpdate to getSnapshotBeforeUpdate plus componentDidUpdate. The UNSAFE_ prefix only hides the warning. React 19 removes both.

    : error in React projects
    No autofix
  • react-doctor/no-legacy-context-api

    Swap childContextTypes + getChildContext for const MyContext = createContext(...) and <MyContext.Provider value={...}>. Swap contextTypes for static contextType = MyContext or useContext() in a function component. Move the provider and every consumer together, or some consumers read the wrong context.

    : error in React projects
    No autofix