简体   繁体   English

React.js和ES6:任何不绑定构造函数中的函数的原因

[英]React.js and ES6: Any reason not to bind a function in the constructor

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. 我正在将React组件更新到ES6并遇到此问题中描述的问题 - 无法在事件处理程序中访问React实例(this) - 即不绑定到组件实例。

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. 您可以直接在render中绑定它,这意味着每次组件渲染时都会创建一个新函数,或者在构造函数中绑定它,这只会触发一次。

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

vs 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? 或者没关系?

Downside of binding in the constructor: react hot loader won't work. 构造函数中绑定的缺点:反应热加载器将无法正常工作。

Downside of binding in render(): performance. render()中绑定的缺点:性能。


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. 它比渲染中的绑定稍快,但我愿意将性能换成灵活性和我梦寐以求的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. 例如,它提供了更多的灵活性,并且更容易过渡到规范的Input原子。

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. 我想你要理解的是Function.prototype.bind()将返回一个新函数。 So you'll basically be doing a creation every time by performing the binding action in the render() method. 因此,您每次都会通过在render()方法中执行绑定操作来进行创建。 Chances of the render() method being called multiple times is really high. 多次调用render()方法的可能性非常高。

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. 即使多次调用render()方法,也将使用使用不同绑定上下文创建的相同函数。

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 . 在这种情况下箭头功能将自动采用当地的this

eg 例如

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/ 你可以在这里阅读更多相关信息: 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. 但是,您确实失去了仅使用标准函数声明的清晰度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM