react/jsx-no-bind
Disallow `.bind()` and functions created during render as JSX props
A .bind() call, an arrow function or a function expression in a prop creates a new function on every render. The child sees a prop that changed, so React.memo and PureComponent can't skip its render, and an effect that depends on the function runs again.
The rule also follows a prop back to a const or a function declared inside the component.
Configure#
Off by default. To turn it on:
[lint.rules]
"react/jsx-no-bind" = "error" # or "warn"Every option, set to its default:
[lint.rules]
"react/jsx-no-bind" = ["error", {
allowArrowFunctions = false,
allowFunctions = false,
allowBind = false,
ignoreRefs = false,
ignoreDOMComponents = false,
}]Examples#
Reported:
function Toolbar({ onSave, doc }) {
const handleReset = () => doc.reset();
return (
<div>
<Button onClick={() => onSave(doc)} />
<Button onClick={doc.print.bind(doc)} />
<Button onClick={handleReset} />
</div>
);
}Not reported:
function Toolbar({ onSave, doc }) {
const handleSave = useCallback(() => onSave(doc), [onSave, doc]);
return <Button onClick={handleSave} />;
}Options#
| Option | Default | What it does |
|---|---|---|
allowArrowFunctions | false | Allow arrow functions. |
allowFunctions | false | Allow function expressions and declarations. |
allowBind | false | Allow .bind(). |
ignoreRefs | false | Don't check the ref prop. |
ignoreDOMComponents | false | Don't check DOM elements such as <button>. They're never memoized, so a new function costs them nothing. |
With ignoreDOMComponents, components are still checked:
const button = <button onClick={() => save(doc)}>Save</button>;const button = <Button onClick={() => save(doc)}>Save</Button>;When not to use it#
A new function only costs something if the child is memoized or uses the function as a dependency. In most other code an inline arrow function is fine and easier to read. The React Compiler also memoizes these functions for you.