最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React.js and ES6: Any reason not to bind a function in the constructor - Stack Overflow

programmeradmin2浏览0评论

I'm in the process of updating a React component to ES6 and suffered the problem described in this question - Unable to access React instance (this) inside event handler - namely not binding to the component instance.

That made sense and of course worked, but I'm confused about the other part of the answer:

Be aware that binding a function creates a new function. You can either bind it directly in render, which means a new function will be created every time the component renders, or bind it in your constructor, which will only fire once.

constructor() {
  this.changeContent = this.changeContent.bind(this);
}

vs

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

I'm assuming that binding in the constructor is the preferred approach for performance etc, but you know what they say about assume!

What are the trade-offs for these two approaches? Is there ever a situation where one is definitely better than the other? Or does it not matter?

I'm in the process of updating a React component to ES6 and suffered the problem described in this question - Unable to access React instance (this) inside event handler - namely not binding to the component instance.

That made sense and of course worked, but I'm confused about the other part of the answer:

Be aware that binding a function creates a new function. You can either bind it directly in render, which means a new function will be created every time the component renders, or bind it in your constructor, which will only fire once.

constructor() {
  this.changeContent = this.changeContent.bind(this);
}

vs

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

I'm assuming that binding in the constructor is the preferred approach for performance etc, but you know what they say about assume!

What are the trade-offs for these two approaches? Is there ever a situation where one is definitely better than the other? Or does it not matter?

Share Improve this question edited Jun 20, 2020 at 9:12 CommunityBot 11 silver badge asked Jul 8, 2015 at 13:40 MattDuFeuMattDuFeu 1,6554 gold badges16 silver badges26 bronze badges 0
Add a comment  | 

3 Answers 3

Reset to default 12

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>
  );
}

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.

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.

发布评论

评论列表(0)

  1. 暂无评论