问题描述
两者都应避免。
虽然它们都可以工作,但是它们都具有相同的弱点,即它们会导致不必要的渲染,因为该函数是动态创建的,因此将呈现为不同的对象。
您不希望使用任何一种方法,而是要以静态方式创建函数,然后将其传递。对于类似your的东西MenuItem
,它应该只获取路径的字符串,然后使用代码在内部进行路由。如果需要路由器,则应将其传递。
然后,该函数应该是一个前置bind
函数(通常在构造函数中)并刚刚传入。
export class MenuItem extends React.Component {
constructor() {
this.handleClick = () => this.props.router.go(this.props.path);
}
render() {
return (
<Button onClick={ this.handleClick }>Go to link</Button>
);
}
}
您可以在构造函数中使用箭头函数。这样,它不会重新创建每个渲染函数,因此可以避免不必要的渲染。该模式适用于单行简单功能。对于更复杂的函数,还可以将它们创建为单独的函数,然后bind
在构造函数中创建。
export class MenuItem extends React.Component {
handleClick() {
this.props.router.go(this.props.path);
}
constructor() {
this.handleClick = this.handleClick.bind(this);
}
render() { /* same as above */ }
}
关键是每次处理程序都是相同的功能。如果不同(您上面描述的两种方法都不同),那么React会不必要地重新渲染对象,因为每次都会有不同的功能。
以下是两篇文章,其中有更多详细信息:
- https://ryanfunduk.com/articles/never-bind-in-render/
- https://daveceddia.com/avoid-bind-when-passing-props/
解决方法
对于事件处理程序,可以在react中使用闭包吗?例如,我在导航中有一些功能和很多菜单,在导航组件中我使用的是这样的:
handleMenuClick(path) {
return () => router.goTo(path)
}
...
<MenuItem
handleTouchTap={this.handleMenuClick('/home')}
>
还是我应该只喜欢箭头功能?
<MenuItem
handleTouchTap={() => router.goTo('/home')}
>
第一个变种确实使代码更清洁,但是我担心大量此类元素的性能