score:12

Accepted answer

Downside of binding in the constructor: react hot loader won't work.

Downside of binding in render(): performance.


Recently I've been doing this. It's slightly faster than binding in render, but I'm willing to trade the performance for flexibility and my coveted HMR.

render(){
  return <input onChange={(e) => this.handleChange(e.target.value)}>;
}

It gives a little more flexibility, for example, and easier transition to the canonical Input atom.

render(){
  return <input onChange={(x) => this.handleChange(x)}>;
}

Or adding arguments where you want them:

render(){
  return (
    <ul>
      {this.props.data.map((x, i) => {
        // contrived example
        return (
          <li 
            onMouseMove={(e) => this.handleMove(i, e.pageX, e.pageY)}>
          {x}
          </li>
        );
      }}
    </ul>
  );
}

score:2

I think you've addresses the main problems to do with recreating functions. I'd like to highlight another option using arrow functions and property initializers. The arrow functions in this case will automatically adopt the local this.

e.g.

class MyClass extends React.Component {
  changeComponent = (e) => {
    // this will refer to the component
  }

  render = () => {
    return <input onChange={this.changeContent} />;
  }
}

You can read more about it here: http://babeljs.io/blog/2015/06/07/react-on-es6-plus/

When you have many functions you'd want to bind, this may be a better solution. You do lose the cleanness of just using a standard function declaration, though.

score:7

I think all you've to understand is Function.prototype.bind() will return a new function. So you'll basically be doing a creation every time by performing the binding action in the render() method. Chances of the render() method being called multiple times is really high.

So doing that in the constructor means you end up binding only once and you can re-use it as many times as you want. Even if the render() method is called multiple times the same function created with a different bound context will be used.

Yes, ideally you should bind in the constructor. Reminds me of a piece of code (check the constructor) I was going through a couple of weeks back.


Related Query

More Query from same tag