在组件的构造函数中或在渲染方法中绑定方法更好?
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 文档:
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
哪个更好(性能更高),如果是:
甲:
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 文档:
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