传递箭头函数vs传递React中的函数

时间:2018-01-17 15:59:07

标签: javascript reactjs arrow-functions

说我有一个功能:

handleChange = (e) => {
  this.setState({ [e.target.id]: e.target.value });
}

以下内容之间有什么区别:

1

<FormControl value={this.state.password} onChange={this.handleChange} />

2

<FormControl value={this.state.password} onChange={(e) => this.handleChange(e)} />

谢谢!

6 个答案:

答案 0 :(得分:2)

创建anonymous function的第二种情况,执行handleChange方法,从而为其提供context

每次React组件呈现时,都会在第二种情况下创建一个新函数,而不是在第一种情况下,因为handleChange方法的相同引用正被提供给处理程序。

您可能还想查看 how arrow function in render achieve context binding

答案 1 :(得分:0)

  

我们可以在类构造函数中绑定我们的事件处理程序:

我们现在可以在事件句柄

中访问它
class MyClass extends Component {
  constructor(props) {
    super(props)
    this.handleChange = this.handleChange.bind(this)
  }
  handleChange(){
   //you can now access "this" inside handlechange
  } 

}

看起来很好。当我们向我们的类添加更多事件处理程序时,代码应该类似于:

import React, { Component } from 'react'
import { MyInput, MyAnotherInput } from 'myInputs'

class MyComponent extends Component {
  constructor(props) {
    super(props)
    this.handleChange = this.handleChange.bind(this)
    this.handleClick = this.handleClick.bind(this)
    this.handleKeyPress = this.handleKeyPress.bind(this)
  }

  handleChange(e) {
    e.preventDefault()
  }

  handleClick(e) {
    e.preventDefault()
  }

  handleKeyPress(e) {
    e.preventDefault()

    if (e.nativeEvent.keyCode === 13) {
      console.log('This is enter!')
    }
  }

  render() {
    return (
      <div>
        <MyInput
          onChange={ this.handleChange }
          onClick={ this.handleClick }
          onKeyPress={ this.handleKeyPress }
        />
        <MyAnotherInput
          onChange={ this.handleChange }
          onClick={ this.handleClick }
          onKeyPress={ this.handleKeyPress }
        />
      </div>  
    )
  }
}

这就是我们可以用Babel编译器将es2015作为预设配置。

  

带箭头功能的事件处理程序

正如您可能已经看到的,当我们创建事件处理程序方法时,我们总是需要将它添加到构造函数中,以绑定它。相当无聊。说实话,创建构造函数方法仅用于绑定方法是没有意义的。应该有另一个解决方案,并且有。

您需要的只是安装Stage-1 Babel预设并使用箭头功能。如果您不知道,怎么做,请转到Babel文档,这非常好。

在我们的案例中,我们可以编写类似这样的东西,而不是绑定方法:

render() {
   return(<MyInput onChange={ (e) => this.handleOnChange(e) } />)
}
  

我们已经创建了新的匿名函数,它会自动绑定它,   这就是为什么我们不需要使用.bind()方法。我们还是一样的   类中的方法,新箭头作为回调中的包装器   属性。

这仍然不是完美的解决方案,因为我们需要更新箭头函数包装器中的参数,并且每次触发render方法时都会创建新实例。 React属性中的箭头函数也不是一个好主意。

答案 2 :(得分:0)

在渲染中使用箭头功能可能会导致一些性能问题。

我建议你在class属性中使用arrow函数,但是你必须使用stage-2功能。

在这里,您可以找到选项之间的比较:

https://medium.freecodecamp.org/react-binding-patterns-5-approaches-for-handling-this-92c651b5af56

答案 3 :(得分:0)

假设您的事件处理程序在您的类中编写如此

handleChange = (e) => {
  this.setState({ [e.target.id]: e.target.value });
}

让我们转到你提到的第一个例子。

<FormControl value={this.state.password} onChange={this.handleChange} />

在这里,对于每个更改,您将传递handleChange函数的内存引用,并且正在传递事件对象。

转到第二种方法。

<FormControl value={this.state.password} onChange={(e) => this.handleChange(e)} />

在这里,您将创建一个新的匿名函数,每次发生事件更改时,该函数都会将事件对象作为参数。如果您有大量列表项,这会大大增加垃圾收集。在这种情况下添加箭头函数是多余的,因为最初由于您编写handleChange方法的方式已经绑定了上下文。作为一个性能提示,如果您在类中使用箭头函数,请使用选项1作为事件处理程序。

答案 4 :(得分:-1)

在第一种情况下,您使用handleChange作为事件处理程序。

在第二种情况下,您使用新函数作为事件处理程序,而后者又调用handleChange

不同之处在于第二个示例中将有两个函数调用。否则他们是一样的。

换句话说:没有必要使用第二种形式,它甚至可能不利于重新渲染。

答案 5 :(得分:-3)

在JavaScript中处理事件时,开箱即用的this上下文可能非常混乱,您可以read more excellent writeup对其进行处理。

回到你的问题,第一种方式onChange={this.handleChange}不保证this中的handleChange()上下文始终是同一个组件实例,在很多情况下,this会请参阅发出onChange事件的FormControl实例。

第二种方法使用箭头语法,它将保证this始终是处理事件的React组件实例。

简而言之,在React组件类中使用箭头语法进行事件处理是首选,因为它保证了一致的this上下文。