为什么以及何时我们需要在 React 中绑定函数和事件处理程序?
Why and when do we need to bind functions and eventHandlers in React?
class SomeClass extends Component{
someEventHandler(event){
}
render(){
return <input onChange={------here------}>
}
}
我看到 ------here------
部分的不同版本。
// 1
return <input onChange={this.someEventHandler.bind(this)}>
// 2
return <input onChange={(event) => { this.someEventHandler(event) }>
// 3
return <input onChange={this.someEventHandler}>
版本有何不同?还是只是偏好问题?
感谢大家的回答和评论。所有这些都是有帮助的,如果你和我一样对此感到困惑,我强烈建议阅读这篇 link FIRST。
http://blog.andrewray.me/react-es6-autobinding-and-createclass/
为什么要绑定一个 React 函数?
当您使用 ES6 class 定义组件时,一个常见的模式是事件处理程序是 class 上的一个方法。在JavaScript中,class方法默认不绑定。如果你忘记了bind this.someEventHandler
而把它传给了onChange
,那么当函数真正被调用时,这将是未定义的。
一般来说,如果你引用的方法后面没有()
,比如onChange={this.someEventHandler}
,你应该绑定那个方法。
可以通过三种方式将 onChange
函数绑定到正确的上下文
第一
return <input onChange={this.someEventHandler.bind(this)}>
在这一个中,我们明确地使用 bind
来使 onChange 事件作为 eventHandler 的参数可用。我们还可以发送一些其他语法类型的参数,如
return <input onChange={this.someEventHandler.bind(this, state.value)}>
第二
return <input onChange={(event) => { this.someEventHandler(event) }>
这是 ES6 语法,我们可以通过它指定要传递给 someEventHandler
函数的参数。这相当于 .bind(this)
然而,它也让我们可以灵活地随事件一起发送其他属性,例如
return <input onChange={(event, value) => { this.someEventHandler(event, value) }>
第三
使用箭头函数定义函数 someEventHandler
someEventHandler = () => {
console.log(this); // now this refers to context of React component
}
arrow function
没有自己的 this
,使用封闭执行上下文的 this
值,因此上述函数获得正确的上下文。
或在构造函数中绑定它像
constructor(props) {
super(props);
this.someEventHandler = this.someEventHandler.bind(this);
}
return <input onChange={this.someEventHandler}>
在此方法中,事件直接附加到 someEventHandler
函数。不能通过这种方式传递其他参数
绑定不是 React 特有的东西,而是 this
在 Javascript 中的工作方式。每个函数/块都有自己的上下文,因为函数更具体到它的调用方式。在添加 ES6 支持时(class语法)。
何时绑定上下文取决于函数的用途,如果您需要访问 class 上的道具、状态或其他成员,则需要绑定它。
对于您的示例,每个都是不同的,这取决于您的组件的设置方式。
预绑定到您的 class
.bind(this)
用于将 this 上下文绑定到您的组件函数。但是,它 returns 每个渲染周期都会引用一个新函数!如果您不想绑定函数的每次使用(例如在点击处理程序中),您可以预先绑定该函数。
a. 在构造函数中进行绑定。又名
class SomeClass extends Component{
constructor(){
super();
this.someEventHandler = this.someEventHandler.bind(this);
}
someEventHandler(event){
}
....
}
b. 在 class 粗箭头函数上创建自定义函数。又名
class SomeClass extends Component{
someEventHandler = (event) => {
}
....
}
运行时绑定到您的 class
执行此操作的几种常用方法
a. 您可以使用内联 lambda(粗箭头)函数包装您的组件处理函数。
onChange={ (event) => this.someEventHandler(event) }
这可以提供额外的功能,比如如果您需要为点击处理程序传递额外的数据 <input onChange={(event) => { this.someEventHandler(event, 'username') }>
。 bind
也可以这样做
b. 你可以使用 .bind(this)
如上所述。
onChange={ this.someEventHandler.bind(this) }
带有附加参数 <input onChange={ this.someEventHandler.bind(this, 'username') }>
如果您想避免创建新的函数引用但仍需要传递参数,最好将其抽象为子组件。
在你的例子中
// 1
return <input onChange={this.someEventHandler.bind(this)}>
这只是将运行时事件处理程序绑定到您的 class。
// 2
return <input onChange={(event) => this.someEventHandler(event) }>
另一个运行时绑定到您的 class。
// 3
return <input onChange={this.someEventHandler}>
您只是将函数作为回调函数传递给点击事件发生时触发,没有额外的参数。确保预先绑定它!
总结一下。考虑如何优化您的代码是件好事,每种方法都有一个实用程序/目的,具体取决于您的需要。
class SomeClass extends Component{
someEventHandler(event){
}
render(){
return <input onChange={------here------}>
}
}
我看到 ------here------
部分的不同版本。
// 1
return <input onChange={this.someEventHandler.bind(this)}>
// 2
return <input onChange={(event) => { this.someEventHandler(event) }>
// 3
return <input onChange={this.someEventHandler}>
版本有何不同?还是只是偏好问题?
感谢大家的回答和评论。所有这些都是有帮助的,如果你和我一样对此感到困惑,我强烈建议阅读这篇 link FIRST。
http://blog.andrewray.me/react-es6-autobinding-and-createclass/
为什么要绑定一个 React 函数?
当您使用 ES6 class 定义组件时,一个常见的模式是事件处理程序是 class 上的一个方法。在JavaScript中,class方法默认不绑定。如果你忘记了bind this.someEventHandler
而把它传给了onChange
,那么当函数真正被调用时,这将是未定义的。
一般来说,如果你引用的方法后面没有()
,比如onChange={this.someEventHandler}
,你应该绑定那个方法。
可以通过三种方式将 onChange
函数绑定到正确的上下文
第一
return <input onChange={this.someEventHandler.bind(this)}>
在这一个中,我们明确地使用 bind
来使 onChange 事件作为 eventHandler 的参数可用。我们还可以发送一些其他语法类型的参数,如
return <input onChange={this.someEventHandler.bind(this, state.value)}>
第二
return <input onChange={(event) => { this.someEventHandler(event) }>
这是 ES6 语法,我们可以通过它指定要传递给 someEventHandler
函数的参数。这相当于 .bind(this)
然而,它也让我们可以灵活地随事件一起发送其他属性,例如
return <input onChange={(event, value) => { this.someEventHandler(event, value) }>
第三
使用箭头函数定义函数 someEventHandler
someEventHandler = () => {
console.log(this); // now this refers to context of React component
}
arrow function
没有自己的 this
,使用封闭执行上下文的 this
值,因此上述函数获得正确的上下文。
或在构造函数中绑定它像
constructor(props) {
super(props);
this.someEventHandler = this.someEventHandler.bind(this);
}
return <input onChange={this.someEventHandler}>
在此方法中,事件直接附加到 someEventHandler
函数。不能通过这种方式传递其他参数
绑定不是 React 特有的东西,而是 this
在 Javascript 中的工作方式。每个函数/块都有自己的上下文,因为函数更具体到它的调用方式。在添加 ES6 支持时(class语法)。
何时绑定上下文取决于函数的用途,如果您需要访问 class 上的道具、状态或其他成员,则需要绑定它。
对于您的示例,每个都是不同的,这取决于您的组件的设置方式。
预绑定到您的 class
.bind(this)
用于将 this 上下文绑定到您的组件函数。但是,它 returns 每个渲染周期都会引用一个新函数!如果您不想绑定函数的每次使用(例如在点击处理程序中),您可以预先绑定该函数。
a. 在构造函数中进行绑定。又名
class SomeClass extends Component{
constructor(){
super();
this.someEventHandler = this.someEventHandler.bind(this);
}
someEventHandler(event){
}
....
}
b. 在 class 粗箭头函数上创建自定义函数。又名
class SomeClass extends Component{
someEventHandler = (event) => {
}
....
}
运行时绑定到您的 class
执行此操作的几种常用方法
a. 您可以使用内联 lambda(粗箭头)函数包装您的组件处理函数。
onChange={ (event) => this.someEventHandler(event) }
这可以提供额外的功能,比如如果您需要为点击处理程序传递额外的数据 <input onChange={(event) => { this.someEventHandler(event, 'username') }>
。 bind
b. 你可以使用 .bind(this)
如上所述。
onChange={ this.someEventHandler.bind(this) }
带有附加参数 <input onChange={ this.someEventHandler.bind(this, 'username') }>
如果您想避免创建新的函数引用但仍需要传递参数,最好将其抽象为子组件。
在你的例子中
// 1
return <input onChange={this.someEventHandler.bind(this)}>
这只是将运行时事件处理程序绑定到您的 class。
// 2
return <input onChange={(event) => this.someEventHandler(event) }>
另一个运行时绑定到您的 class。
// 3
return <input onChange={this.someEventHandler}>
您只是将函数作为回调函数传递给点击事件发生时触发,没有额外的参数。确保预先绑定它!
总结一下。考虑如何优化您的代码是件好事,每种方法都有一个实用程序/目的,具体取决于您的需要。