Which of the following is the best practice with regard to performance in a React class component:
Binding a call back function in the constructor:
constructor(props)
{
/* some code */
this.onChange= this.onChange.bind(this)
}
render() {
return(
<div>
<input onChange={this.onChange}
</div>
);
}
onChange(event) {
/* some code involving 'this' */
}
Using an arrow function instead of a normal function:
constructor(props)
{
/* some code */
}
render() {
return(
<div>
<input onChange={this.onChange}
</div>
);
}
onChange = (event) => {
/* some code involving 'this' */
}
Sticking to a normal function but declaring an arrow function in the onChange field:
constructor(props)
{
/* some code */
}
render() {
<div>
<input onChange={(event) => {this.onChange(event)}}
</div>
}
onChange(event) {
/* some code involving 'this' */
}
Thanks!
All 3 options, with regards to this
, behave the same.
Option 3 is creating a new function on every render and is thus less desired than options 1 and 2 (since such re-creation is unnecessary and could potentially hinder performance)
As far as options 1 and 2, they come down to the same behavior with slight differences unrelated to the behavior of this
.
The trick to understanding why they behave the same with this
is to know what the following code does:
method = () => {}
It's just syntactic sugar to add a method to an instance:
class A {
method = () => {}
}
// is the same as
class A {
constructor() {
this.method = () => {}
}
}
See how Babel transpiles it.
Since an arrow function inherits the context it is defined in as this
, the context for option 2 is the class itself.
class A {
constructor() {
this.method = () => {
return this;
// ^^^^ this points to the instance of A
}
}
}
const a = new A();
console.log(a.method() === a); // true
Which is the same thing for option 1:
class A {
constructor() {
this.method = this.method.bind(this);
}
method() {
return this;
// ^^^^ this points to the instance of A
}
}
const a = new A();
console.log(a.method() === a); // true
That means your options come down to the difference between:
// option 1
constructor(props) {
this.onChange = this.onChange.bind(this)
}
onChange() {
// code for onChange...
}
and
// option 2
constructor(props) {
this.onChange = () => /* code for onChange */
}
The main advantage I would give to option 1 is that it has a named function instead of an arrow function, which makes debugging a bit easier when examining stack traces (although function name inferences dilutes this point a bit).
The main advantage I would give to option 2 is that it's a bit "cleaner" looking, as in less verbose, code but that is a subjective opinion.
Overall, option 1 and option 2 are practically indifferent.