Prefer Arrow Functions Over bind
Arrow functions can be an attractive alternative to function expressions for callbacks or function arguments. They are automatically bound to their surrounding scope/context. This provides an alternative to the pre-ES6 standard of explicitly binding function expressions to achieve similar behavior.
Additionally, arrow functions are
- less verbose, and easier to reason about which improves the readability of the code.
- bound lexically regardless of where or when they are invoked.
Anyway, please note that there are some differences between arrow functions and binding:
- Arrow functions are always anonymous, which means e.g. it is not possible to reliably call them recursively since there is no reliable lexical name to use.
- Arrow functions actually create lexical bindings for
this
,super
, andarguments
. Onlythis
is bound by.bind()
. Arrow functions cannot be used innew
expressions, while.bind()
bound functions can.
ESLint: prefer-arrow-callback
Examples
⇣ Incorrect code for this rule:
snow(function(flake) {
return flake;
});
snow(
function() {
return this.flake;
}.bind(this)
);
⇡ Correct code for this rule:
snow(flake => flake);
References
No Binding Or Arrow Functions In Render
Do not use .bind()
or arrow functions in render
. A bind
call or arrow function in a JSX prop will create a brand new function on every single render which is bad for performance, as it will result in the garbage collector being invoked way more than is necessary. It may also cause unnecessary re-renders if a brand new function is passed as a prop to a component that uses reference equality check on the prop to determine if it should update.
Note when used in class fields, it makes them challenging to test and debug, and can negatively impact performance, and because conceptually, class fields are for data, not logic.
Arrow functions are also good to close over local variables. It is handy when used to pass additional data to an event handler. Although, make sure they do not massively hurt performance, in particular when passed to custom components that might be PureComponents
, because they will trigger a possibly needless re-render every time.
ESLint: react/jsx-no-bind
Examples
⇣ Incorrect code for this rule:
class Snow extends React.Component {
onSnowflakeClick() {
// ...
}
render() {
return <div onClick={this.onSnowflakeClick.bind(this)} />;
}
}
⇡ Correct code for this rule:
class Snow extends React.Component {
constructor(props) {
super(props);
this.onSnowflakeClick = this.onSnowflakeClick.bind(this);
}
onSnowflakeClick() {
// ...
}
render() {
return <div onClick={this.onSnowflakeClick} />;
}
}
⇢ Recommended code for this rule:
class Snow extends React.Component {
onSnowflakeClick = () => {
// ...
};
render() {
return <div onClick={this.onSnowflakeClick} />;
}
}
References
- Arrow Functions in Class Properties Might Not Be As Great As We Think
- Why arrow functions and bind in React’s Render are problematic
- Arrow functions vs. bind()
No Underscore Prefix
Do not use underscore prefix for internal methods of a React component. Underscore prefixes are sometimes used as a convention in other languages to denote privacy. But, unlike those languages, there is no native support for privacy in JavaScript, everything is public. Regardless of the intentions, adding underscore prefixes to properties does not actually make them private, and any property (underscore-prefixed or not) should be treated as being public. See issues airbnb/javascript#1024 and airbnb/javascript#490 for a more in-depth discussion.
Examples
⇣ Incorrect code for this rule:
class Snow extends React.Component {
_onFalling() {
// ...
}
}
⇡ Correct code for this rule:
class Snow extends React.Component {
onFalling() {
// ...
}
}
Render Return
Be sure to return a value in the render
function.
ESLint: react/require-render-return
Examples
⇣ Incorrect code for this rule:
render() {
(<div />);
}
⇡ Correct code for this rule:
render() {
return (<div />);
}