我理解绑定事件处理程序的概念,以便他们获得对this
的正确引用。我的问题是,为什么引用一个类的方法没有提供正确的this
?
ES6类是否不会自动为类方法提供this
?
class MyComponent extends Component {
clickHandler(event) {
console.log('this', this);
}
render() {
return <button onClick={this.clickHandler}>Button</button>;
}
}
正如预期的那样,上面的代码将打印null
以获取this
的值。但是,显式调用处理程序将给出正确的值,即<button onClick={event => this.clickHandler(event)} />
。为什么处理程序使用箭头函数对this
有正确的引用?
我可以假设一堆答案,但我喜欢正确的答案。
答案 0 :(得分:1)
为什么事件处理程序没有得到正确的处理?
他们这样做!正常情况下,他们会引用您挂钩事件的元素。
ES6类是否不会自动为类方法提供
this
?
他们没有,没有; ES2015(“ES6”)类使用与ES5及之前相同的基本原型继承和this
赋值,具有不同的语法(以及一些新功能)。
但是,显式调用处理程序将给出正确的值
是的,出于同样的原因,在此代码中,使用example
调用this
来引用x
:
x.example();
...但在此代码中,调用example
时this
为undefined
(在严格模式下;它将是松散模式下的全局对象):
let e = x.example;
e();
使用class
并不会改变对this
管理的需求。
要使this
引用组件类,您需要将this
绑定到它,或者使用关闭this
的箭头函数来使用:
绑定(一种相当常见的模式):
class MyComponent extends Component {
constructor(...args) { // ***
super(...args); // ***
this.clickHandler = this.clickHandler.bind(this); // ***
} // ***
clickHandler(event) {
console.log('this', this);
}
render() {
return <button onClick={this.clickHandler}>Button</button>;
}
}
使用箭头功能(也很常见):
class MyComponent extends Component {
clickHandler = event => { // ***
console.log('this', this);
}; // ***
render() {
return <button onClick={this.clickHandler}>Button</button>;
}
}
后一种选择假设您正在转发支持即将到来的public class fields,这些尚未标准化。 (截至撰写本文时,该提案在still处为stage 2。)不是在原型上创建属性,而是创建一个带箭头函数的实例字段,该函数关闭this
(其中是对组件实例的引用。