Reputation: 100000
I am new to ES6 with React, and see this inexplicable code in a component:
componentWillUnmount() {
base.removeBinding(this.ref);
this.unsubscribe();
}
// ES6 syntax
handleToggle(event, toggled){
this.setState({
[event.target.name]: toggled,
});
};
// possible ES8 syntax
handleToggle = (event, toggled) => {
this.setState({
[event.target.name]: toggled,
});
};
the second method is confusing me, what exactly is happening with the handleToggle method? Is there an ES5 equivalent?
My guess that the ES5 equivalent is:
componentWillUnmount: function() {
base.removeBinding(this.ref);
this.unsubscribe();
}
handleToggle: (event, toggled) => {
this.setState({
[event.target.name]: toggled,
});
};
...the problem/confusing part with the second method, is that 'this' in the handleToggle method will be bound to the wrong value (the lexical scope 'this' value)...so is this syntax even valid here?
what is going on? This is code in someone else's library that I wish to understand.
Upvotes: 0
Views: 1744
Reputation: 816364
what exactly is happening with the handleToggle method?
This is a new feature that is a proposal called public class fields. Currently the ES6 class syntax only provides syntactic support for defining shared methods, but not for instance methods/properties. This proposals extend the class syntax to support that.
Here is a simple example:
class Foo {
bar = 42;
}
is equivalent to
class Foo {
constructor() {
this.bar = 42;
}
}
I.e. those properties are evaluated as if they are assign to this
inside the constructor.
Consequently your example is equivalent to
class Component extends React.Component {
constructor()
this.handleToggle = (event, toggled) => {
this.setState({
[event.target.name]: toggled,
});
};
}
}
Due to the nature of arrow functions, this creates "bound" instance methods and thus can be passed to other functions without loosing the value of this
.
so is this syntax even valid here?
No officially released version of ECMAScript contains this feature, so strictly speaking the answer should be: no. However, it is on the standards track, so it will likely be part of ES2018.
In the meantime its possible to use this proposal in your own code by using Babel (which needs to be used for React anyway) with the transform-class-properties
plugin.
Upvotes: 4
Reputation: 281656
The handleToggle function here makes use of the arrow functions
handleToggle = (event, toggled) => {
this.setState({
[event.target.name]: toggled,
});
};
It takes two arguments event, toggled
and whatever is after the =>
is the body of the function. One speciality of arrow functions is that is does the binding action too.
The ES5 equivalent of the above function would be
handleToggle: function(event, toggled){
this.setState({
[event.target.name]: toggled,
});
};
while calling this function you will need to bind it explicitly like this.handleToggle.bind(this, value)
Upvotes: 0