Reputation: 3338
Which is better (more performant), if one it is:
A:
class Man extends React.Component {
constructor(props) {
super(props)
this.talk = this.talk.bind(this)
this.state = {}
}
talk() { .. }
render () {
return <div onClick={this.talk}>talk!</div>
}
}
B:
class Man extends React.Component {
constructor(props) {
super(props)
this.state = {}
}
talk() { .. }
render () {
return <div onClick={this.talk.bind(this)}>talk!</div>
}
}
C:
class Man extends React.Component {
constructor(props) {
super(props)
this.state = {}
}
talk() { .. }
render () {
return <div onClick={() => this.talk()}>talk!</div>
}
}
I think that calling the bind
method directly in the render
method could be negligible, but after all the render method is called ton of times. I want to understand if making a change in a big codebase is it worth it or not.
Upvotes: 3
Views: 3541
Reputation: 4080
The best solution will be auto binding internal methods. using arrow functions as methods.
So we don't rely on the constructor to bind the internal methods, and for example having multiple internal methods will just increase the number of lines of your files unnecessarily
Here is an implementation of what I'm saying:
class Man extends React.Component {
constructor(props) {
super(props)
this.state = {};
}
talk = () => { .. }
render () {
return <div onClick={this.talk}>talk!</div>
}
}
In order for this to work, you should use transform-class-properties from Babel Stage 2 preset
Upvotes: 3
Reputation: 104379
As per React DOC (last para of the page):
onClick={(e) => this.handleClick(e)}
and onClick={this.talk.bind(this)}
The problem with this syntax is that a different callback is created each time the component renders. In most cases, this is fine. However, if this callback is passed as a prop to lower components, those components might do an extra re-rendering. We generally recommend binding in the constructor or using the property initializer syntax, to avoid this sort of performance problem.
MDN DOC:
The bind() method creates a new function always.
Binding method in the constructor:
However if you bind
the method in the constructor
:
this.handleClick = this.handleClick.bind(this);
and use it like this:
onClick={this.handleClick}
It will create only one instance and use that instance always. So binding method in the constructor means you end up binding only once and you can re-use it as many times, even if the render() method is called multiple times the same function will be used.
property initilizer syntax (this is experimental syntax.):
By this way you don't need to bind
all the methods in the constructor
, and it will not create multiple callbacks also.
handleClick = () => {
.....
}
Upvotes: 4
Reputation: 3238
I think you should do binding in constructor as calling bind returns a new function. It should be called one time for performance reasons. In you call it in render, bind will be called on every render and will return a new reference each time.
Upvotes: 0
Reputation: 7593
If we are to define 'more performant' as something that requires the least amount of computational resource, then option A (binding in the constructor) would be the most performant.
As you state, this is because this only happens once during the creation of an instance of the component. The .bind
returns a newly bound function which is referenced later on.
The latter two options will be creating new functions (bound or anonymous) on every render, which is not necessary in this context.
Upvotes: 1