React 中的闭包

IT技术 javascript reactjs
2021-05-13 06:09:42

对于事件处理程序,可以在react中使用闭包吗?例如,我在导航和导航组件中有一些功能和很多菜单,我使用这样的东西:

handleMenuClick(path) {
  return () => router.goTo(path)
}
... 
<MenuItem
  handleTouchTap={this.handleMenuClick('/home')}
>

或者我应该更喜欢箭头函数?

<MenuItem
  handleTouchTap={() => router.goTo('/home')}
>

第一个变体确实使代码更清晰,但我担心大量此类元素的性能

2个回答

两者都应该避免。

虽然它们都可以工作,但它们都有相同的弱点,即它们会导致不必要的渲染,因为函数是动态创建的,因此将作为不同的对象呈现。

您希望以静态方式创建函数,然后将它们传入,而不是其中任何一个。对于类似您的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 会不必要地重新渲染对象,因为它每次都是不同的函数。

这里有两篇文章更详细:

当您在react组件(对象)中定义新方法时,因为我们知道函数是 javascript 中的对象。

 let reactComponent={
addition: function(){ //some task ...},
render: function(){},
componentWillMount : function(){},
}

所以,每个新方法都应该使用 bind 绑定到对象中,但是 render() 已经定义了所以我们不这样做

this.render = this.render.bind(this)

对于每个新函数,除了需要添加react生命周期方法,因此,我们使用 this.method() 调用对象(构造函数)方法。