在组件的构造函数中或在渲染方法中绑定方法更好?

It is better bind methods in the constructor of a component or in the render method?

哪个更好(性能更高),如果是:

甲:

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

乙:

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

我觉得在render方法中直接调用bind方法可以忽略不计,毕竟render方法调用了很多次。我想了解对大型代码库进行更改是否值得。

如果我们要将 'more performant' 定义为需要最少计算资源的东西,那么选项 A(在构造函数中绑定)将是最高性能的。

如您所说,这是因为这只在创建组件实例期间发生一次。 .bind returns 一个新绑定的函数,稍后会引用。

后两个选项将在每个渲染器上创建新函数(绑定或匿名),这在这种情况下不是必需的。

根据 React DOC(页面的最后一段):

onClick={(e) => this.handleClick(e)}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 文档:

Function.prototype.bind():

The bind() method creates a new function always.

构造函数中的绑定方法:

但是,如果您 bind constructor 中的方法:

this.handleClick = this.handleClick.bind(this);

并像这样使用它:

onClick={this.handleClick}

它将只创建一个实例并始终使用该实例。所以构造函数中的绑定方法意味着你最终只绑定一次,你可以多次重复使用它,即使多次调用 render() 方法也会使用相同的函数。

property initilizer syntax(这是 实验性 语法。):

通过这种方式,您不需要 bind constructor 中的所有方法,也不会创建多个回调。

handleClick = () => {
   .....
}

我认为您应该在构造函数中进行绑定,就像调用 bind returns 一个新函数一样。出于性能原因,它应该被调用一次。在渲染中调用它时,每次渲染都会调用绑定,并且每次都会 return 一个新引用。

最好的解决方案是自动绑定 内部方法。使用箭头函数作为方法。

所以我们不依赖构造函数来绑定内部方法,例如拥有多个内部方法只会不必要地增加文件的行数

这是我所说内容的实现:

class Man extends React.Component {
  constructor(props) {
    super(props)
    this.state = {};
  }

  talk = () => { .. }

  render () {
    return <div onClick={this.talk}>talk!</div>
  }
}

为了让它工作,你应该使用transform-class-properties from Babel Stage 2 preset