jsx-no-bind
Configuration
rslint.config.ts
Disallow .bind() or arrow functions in JSX props.
Rule Details
A new function (or an arrow function) is created on every render when .bind() or an inline function expression is used as a JSX prop. Passing a new function reference can trigger unnecessary re-renders in memoized consumers or cause effects to re-run.
Examples of incorrect code for this rule:
Examples of correct code for this rule:
Rule Options
allowArrowFunctions: allow arrow function expressions as JSX prop values.allowBind: allow.bind()calls as JSX prop values.allowFunctions: allow function expressions/declarations as JSX prop values.ignoreRefs: skip checks onrefprops.ignoreDOMComponents: skip checks on DOM components (lowercase tags like<div>).
Differences from ESLint
- The ES bind operator (
::, e.g.<div foo={::this.onChange} />) is not supported. Empirically verified: TypeScript's parser rejects the::token as a syntax error, so such code never reaches the rule. Consequently thebindExpressionmessageId is not produced.
Known Limitations (matches ESLint)
- Identifiers used inside conditional expressions are not resolved against tracked declarations, so
<Foo onClick={cond ? tracked : other} />does not flagtracked. - Only
constdeclarations are tracked;let/varbindings are ignored even when initialized to an arrow / bind / function. - Forward references (JSX used before the declaration in source order) are not reported.
- A non-violating inner
constdoes not shadow a violating outer one; JSX inside the inner scope still reports the outer violation. - TypeScript-only wrappers (
as T,<T>expr,expr!,expr satisfies T) are opaque to the rule, matching ESLint's behavior under the@typescript-eslint/parser: for example<Foo onClick={(() => 1) as Handler} />is not flagged. Plain parentheses around an expression are transparent because ESTree does not represent them as nodes.