Skip to content

[Bug]: jsx-handler-names crashes on compound components #3954

@djankies

Description

@djankies

Is there an existing issue for this?

  • I have searched the existing issues and my issue is unique
  • My issue appears in the command-line and not only in the text editor

Description Overview

react/jsx-handler-names rule crashes with TypeError: Cannot read properties of undefined (reading 'split') when encountering compound components (e.g., <Component.SubComponent />).

Environment

  • eslint-plugin-react: 7.37.5
  • ESLint: 9.36.0
  • Parser: @typescript-eslint/parser

Stack Trace

TypeError: Cannot read properties of undefined (reading 'split')
    at Minimatch.match (node_modules/minimatch/minimatch.js:743:9)
    at minimatch (node_modules/minimatch/minimatch.js:125:42)
    at node_modules/eslint-plugin-react/lib/rules/jsx-handler-names.js:146:99

Root Cause

The rule incorrectly assumes node.parent.name.name exists for all components:

// Line 144 in jsx-handler-names.js
const componentName = node.parent.name.name;  // Returns undefined for compound components

const isComponentNameIgnored = ignoreComponentNames.some((pattern) => minimatch(
  componentName,  // undefined passed to minimatch
  pattern
));

AST Structure Difference

Component Type JSX node.parent.name
Simple <Button /> { type: 'JSXIdentifier', name: 'Button' }
Compound <Select.Option /> { type: 'JSXMemberExpression', object: {...}, property: {...} }

For JSXMemberExpression, there's no .name property at the root level, causing undefined to be passed to minimatch().

Minimal Reproduction

// test.jsx
const Component = () => {
  const handleChange = () => {};
  return <Select.Option onChange={handleChange} />;  // Crashes here
};
// eslint.config.mjs
export default [{
  plugins: { react: reactPlugin },
  rules: {
    'react/jsx-handler-names': ['warn', {
      eventHandlerPrefix: 'handle',
      eventHandlerPropPrefix: 'on'
    }]
  }
}];

Run: npx eslint test.jsx → TypeError

Workaround

Disable the rule for files with compound components:

export default [
  { rules: { 'react/jsx-handler-names': ['warn', {...}] } },
  {
    files: ['**/files-with-compound-components.tsx'],
    rules: { 'react/jsx-handler-names': 'off' }
  }
];

Expected Behavior

  1. Successfully parse compound components without crashing
  2. Apply handler naming conventions to compound components (e.g., warn if <Select.Option onClick={doSomething} /> doesn't follow the configured naming pattern)
  3. Support ignoreComponentNames patterns for compound components (e.g., 'Select.*' or '*.Option')

eslint-plugin-react version

v7.37.5

eslint version

v9.36.0

node version

v23.5.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions