react/jsx-handler-names

Enforce naming conventions for event handlers and the props they are passed to

In a common React convention, a prop that takes an event handler starts with on, and the function that handles the event starts with handle. The rule reports an on prop that gets a function with another name, and a handle function that's passed to a prop with another name. Passing a prop through, as in onBlur={props.onBlur}, is fine.

By default the rule only checks members such as this.handleChange. It skips local variables and inline functions, and it never checks ref.

Configure#

Off by default. To turn it on:

bunfig.toml
[lint.rules]
"react/jsx-handler-names" = "error" # or "warn"

Every option, set to its default:

bunfig.toml
[lint.rules]
"react/jsx-handler-names" = ["error", {
  eventHandlerPrefix = "handle",
  eventHandlerPropPrefix = "on",
  checkLocalVariables = false,
  checkInlineFunction = false,
  ignoreComponentNames = [], # list of strings
}]

Examples#

example.jsx2 problems
class Form extends React.Component {
  render() {
    return <Input onChange={this.updateName} blur={this.handleBlur} />;
  }
}
example.jsxNo problems
class Form extends React.Component {
  render() {
    return (
      <Input
        onChange={this.handleChange}
        onBlur={this.props.onBlur}
        onFocus={() => this.track("focus")}
        ref={this.handleRef}
      />
    );
  }
}

Options#

OptionDefaultWhat it does
eventHandlerPrefix"handle"The prefix for a handler function.
eventHandlerPropPrefix"on"The prefix for a prop that takes a handler.
checkLocalVariablesfalseAlso check handlers that are plain variables, such as onChange={updateName}.
checkInlineFunctionfalseAlso check the function that an arrow function calls, such as onChange={() => this.updateName()}.
ignoreComponentNames[]Components to skip. A name can be a glob pattern.

Function components keep their handlers in local variables, so they need checkLocalVariables:

example.jsxwith { "checkLocalVariables": true }1 problem
function Form() {
  const updateName = event => setName(event.target.value);
  return <Input onChange={updateName} />;
}
example.jsxwith { "checkLocalVariables": true }No problems
function Form() {
  const handleChange = event => setName(event.target.value);
  return <Input onChange={handleChange} />;
}

With checkInlineFunction:

example.jsxwith { "checkInlineFunction": true }1 problem
const field = <Input onChange={() => this.updateName()} />;

With other prefixes, here "do" and "when":

example.jsxwith { "eventHandlerPrefix": "do", "eventHandlerPropPrefix": "when" }1 problem
const field = <Input whenChange={this.handleChange} />;

With ignoreComponentNames set to ["Legacy*"]:

example.jsxwith { "ignoreComponentNames": ["Legacy*"] }No problems
const field = <LegacyInput onChange={this.updateName} />;

Either prefix can also be false. Both checks need both prefixes, so that turns the whole rule off:

example.jsxwith { "eventHandlerPropPrefix": false }No problems
const field = <Input onChange={this.updateName} blur={this.handleBlur} />;
example.jsxwith { "eventHandlerPrefix": false }No problems
const field = <Input onChange={this.updateName} blur={this.handleBlur} />;