I'm following reactjs handling-events documentation, and I came across this:
In JavaScript, class methods are not bound by default. If you forget to bind this.handleClick and pass it to onClick, this will be undefined when the function is actually called.
What I understand from this quotation is that this
doesn't designate the current instantiation in every class methods.
However, if I consider the code below, the method editState
can access the property state
of the extended class Parent
through this
. Which would make false the previous quotation, as this
is bound to all the class mehtods.
class Parent {
constructor() {
this.state = false;
}
setState(newState) {
this.state = newState;
}
}
class Child extends Parent {
editState() {
this.setState(true);
}
}
let c = new Child;
c.editState();
console.log(c.state);
What am I missing here?
When we bind the this of the event handler to the component instance in the constructor, we can pass it as a callback without worrying about it losing its context. Arrow functions are exempt from this behavior because they use lexical this binding which automatically binds them to the scope they are defined in.
This is because whenever inside a class component when we need to pass a function as props to the child component, we have to do one of the following: Bind it inside the constructor function. Bind it inline (which can have some performance issues).
[React Component Class] Methods follow the same semantics as regular ES6 classes, meaning that they don't automatically bind this to the instance.
TL;DR: Binding callbacks is a JavaScript thing. It's necessary because you have to tell your callback what it's context is. Avoid binding by using the public class fields syntax, or bind your callbacks inside the constructor.
When a function is used as an event handler, its 'this' is set to the element the event fired from. As a DOM event handler
I think the React documentation might be misleading. The React component below MyClass
is a derived class (aka child class) of React.Component
. The constructor
method is a special method within javascript ES6 which is used for creating and initializing an object created with a class. React uses the constructor to pass props
to the component when the object is created. Base classes (aka parent classes) are created bound to their own this
, but the derived classes do not have their own this
by default. The derived class must call super(props) which binds the this
from the base class down into the derived class.
class MyClass extends React.Component{
constructor(props) {
super(props)
}
}
Here is the relevant information from the link provided by user376830's answer. This is straight from the javascript documentation.
The behavior of this
in classes and functions is similar, since classes are functions under the hood. But there are some differences and caveats.
Within a class constructor, this
is a regular object. All non-static methods within the class are added to the prototype of this
:
class Example {
constructor() {
const proto = Object.getPrototypeOf(this);
console.log(Object.getOwnPropertyNames(proto));
}
first(){}
second(){}
static third(){}
}
new Example(); // ['constructor', 'first', 'second']
Note: Static methods are not properties of this
. They are properties of the class itself.
Unlike base class constructors, derived constructors have no initial this
binding. Calling super()
creates a this
binding within the constructor and essentially has the effect of evaluating the following line of code, where Base is the inherited class:
this = new Base();
Warning: Referring to this before calling super()
will throw an error.
Derived classes must not return before calling super()
, unless they return an Object
or have no constructor at all.
class Base {}
class Good extends Base {}
class AlsoGood extends Base {
constructor() {
return {a: 5};
}
}
class Bad extends Base {
constructor() {}
}
new Good();
new AlsoGood();
new Bad(); // ReferenceError
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With