Why do event handlers not get the right handle to this?
They do! They get a reference to the element you hooked the event on, as normal.
Do ES6 classes not automatically provide this
on class methods?
They don't, no; ES2015 ("ES6") classes use the same fundamental prototypical inheritance and this
assignment as ES5 and before, with different syntax (and a couple of new features).
However, explicitly calling the handler will give the correct value
Right, for the same reason that in this code, example
is called with this
referring to x
:
x.example();
...but in this code, example
is called with this
being undefined
(in strict mode; it would be the global object in loose mode):
let e = x.example;
e();
Using class
doesn't change the need for this
management.
To make this
to refer to the component class, you need to either bind this
to it, or use an arrow function that closes over the this
to use:
Binding (a fairly common pattern):
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>;
}
}
Using an arrow function instead (also fairly common):
class MyComponent extends Component {
clickHandler = event => { // ***
console.log('this', this);
}; // ***
render() {
return <button onClick={this.clickHandler}>Button</button>;
}
}
That latter option assumes you're transpiling with support for the upcoming public class fields, which aren't standard yet. (The proposal is still at stage 2 as of this writing.) Instead of creating a property on the prototype, it creates an instance field with an arrow function, which closes over this
(which is a reference to the component instance).