说我有一个功能:
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)} />
谢谢!
答案 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
上下文。