Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best and most efficient way to bind callbacks in ReactJS? In the constructor or in the render method or as a property initializer?

Tags:

Say I have a function in the Parent component that I want to use as a callback for the Child component. Which way is better?

render() {
    return (
        <Child handleClick={this.handleClick.bind(this)} />
    )
}

or

constructor() {
    super();
    this.handleClick = this.handleClick.bind(this);
}

According to this eslint, it is much better to do so in the constructor because the render() method may be called multiple times. This makes perfect sense to me.

However, this just means that the bound function ends up being a property on each and every instance. Thus defeating the entire purpose of the prototype.

I do know about the property initializers:

handleClick = () => {
    // do stuff
}

But it looks this syntax is no where close to being agreed upon for ES2017 (or whatever the next one might be). For this reason, I'm afraid to use this syntax as it might never make it into the language.

So, having said all that, what is the best way to go about this?

like image 926
gjvatsalya Avatar asked Nov 30 '16 00:11

gjvatsalya


1 Answers

Although all options you and other people in comments have said do definitely work, I would go for Airbnb's React styleguide one:

✓ Binding on the constructor

constructor(props) {
  super(props);
  this.foo = this.foo.bind(this);
}

✓ ES7 binding on constructor is also a good option (though keep in mind that it is still a proposal)

constructor(props) {
  super(props);
  this.foo = ::this.foo;
}

What about the other options?

✖ Binding on render

render() {
  return <button onClick={this.handleClick.bind(this}>...</button>
}

Rebinded on every re-render, not to say that if you have two elements that use the same function, you will have to choose whether to leave one without binding or binding both (which would be ugly or more inefficient).

✖ Arrow function (not binding)

render() {
  return <button onClick={(e) => this.handleClick(e)}>...</button>
}

You are going through one more function when there is no need to.

like image 200
zurfyx Avatar answered Sep 23 '22 16:09

zurfyx