react-doctor/no-usememo-simple-expression
Remove useMemo — property access, math, and ternaries are already cheap without memoization
- Category: Performance
- Severity: warn
- Source:
oxlint-plugin-react-doctor - Framework: global
- Enabled when: always
Validation prompt
Use this to decide whether a fired diagnostic is real or a false positive.
Confirm a useMemo(() => expr, ...) whose return is a literal, template literal, arithmetic / comparison of simples, unary, or ternary of simples — NOT a bare identifier or property access (those are intentionally excluded to preserve stable-reference passing). The hook's bookkeeping cost exceeds the computation.
Fix prompt
Use this once validation confirms the diagnostic is real.
Delete the useMemo and inline the expression directly. Math, ternaries, and string concatenation run in nanoseconds — the dependency-array comparison plus cache bookkeeping is the actual overhead. Reserve useMemo for genuinely expensive O(n) work or for stable reference identity that downstream memo / effects depend on. See https://react.dev/reference/react/useMemo#should-you-add-usememo-everywhere
Related rules
More Performance rules from the rules reference:
react-doctor/prefer-stable-empty-fallback: Hoist a module-level const EMPTY = [] (or {}) and use it as the || / ?? fallback so the memoised child sees a stable referencereact-doctor/redux-useselector-inline-derivation: Select the raw slice in useSelector and derive with useMemo, or hoist into a memoised createSelector from reselect.react-doctor/redux-useselector-returns-new-collection: useSelector that returns a fresh object/array literal re-renders on every action; return a primitive, split into multiple useSelector calls, or pass shallowEqual.react-doctor/rendering-animate-svg-wrapper: Wrap the SVG: `<motion.div animate={...}><svg>...</svg></motion.div>`react-doctor/rendering-hoist-jsx: Move the static JSX to module scope: `const ICON = <svg>...</svg>` outside the component so it isn't recreated each render