Skip to content

[bug] no-nested-component-definitions no longer reports components wrapped in useCallback (regression in v5.6.0) #1927

Description

@muyu258

Describe the bug

A nested component wrapped in useCallback is no longer reported. It was reported up to v4.2.3, is
not reported since v5.6.0, and is still missed in v5.18.1.

Cause: the rule skips components with name == null, and getFunctionComponentId() only resolves a
name through a wrapping call when that call is memo / forwardRef (isFunctionComponentWrapperCall).
For useCallback(...) it returns null, so the component is silently skipped.

Note static-components covers this when the component is rendered as JSX, but not when it is only
passed as a prop (e.g. <Select components={{ Option: CustomOption }} />) — in that shape nothing
reports it.

Reproduction

export const Parent = () => {
  const A = () => <div>a</div>;                    // reported
  const B = memo(() => <div>b</div>);              // reported
  const C = useCallback(() => <div>c</div>, []);   // NOT reported (was reported in <= 4.2.3)
  return <Consumer render={{ A, B, C }} />;
};

Only react-x/no-nested-component-definitions enabled. Bisect: 4.2.3 reports C, 5.6.0 and 5.18.1 do not.

Expected behavior

C should be reported. Wrapping a nested component in useCallback does not make it stable — it
still remounts when the deps change — so it should not exempt it from the rule.

Platform and versions

eslint-plugin-react-x 5.18.1 (regression range: 4.2.3 good → 5.6.0 bad)
eslint 10.7.0, typescript 6.0.2, react 18.3.1, node 24.16.0, macOS

Stack trace


Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions