There’s a challenge (Bind ‘this’ to a Class Method) on React certification which includes featuring this
keyword and now I’ve thought up a scenario on what happens when a React component is called. Please help me and read my explanation and let me know if it’s correct or not? My explanation includes what happens when you define your component function (class), what happens when you call your component, what this
refers to in different occasions, binding and some staff I’ve learned so far on OOP!! Please copy the given code into challenge editor to see the results if you need it. And please if I’m wrong refer to what is wrong using the number in front of each explanation
Here’s the code of React component:
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
text: "Hello"
};
}
handleClick() {
this.setState({
text: "You clicked!"
});
}
render() {
return (
<div>
<button onClick={this.handleClick}>Click Me</button>
<h1>{this.state.text}</h1>
</div>
);
}
};
Before looking at what happens when the component is called there are things that happen when defining the component class above:
- 1- Each class is actually a constructor function which itself is an object from type
function
. The functions you define inside your class but outsideconstructor
method is defined on theprototype
property of the class. So nowMyComponent
class’s prototype includeshandleClick
andrender
.
Now to render the React component we do this:
ReactDOM.render(<MyComponent />, document.getElementById("challenge-node"));
-
2- When
MyComponent
is called in the code above, an instance ofMyComponent
class is instantiated and the newly created instance includes some own properties which one of them isstate
. ButhandleClick
andrender
aren’t defined on the instance but as I said on theprototype
. -
3- After the new instance is created,
render
method is called on the instance, butrender
is not an own property so we traverse up the inheritance chain andrender
exists onprototype
and is run. After the markup is returned, our button has a click event listener which instructs to do this:this.handleClick();
. -
4- Here
this
refers to the instance but we don’t havehandleClick
on instance But because of inheritance chain we accesshandleClick
method existing onprototype
. -
5- So when the button is clicked, the
hanleClick
method onprototype
is run which instructs to do this:this.setState({text: "You clicked!"});
-
6- This is the explanation I’m not sure to be true. Here
this
does not refer to anything (is undefined) because we had to travers on inheritance chain! So to preventthis
from being undefined we should prevent traversing inheritance chain so we need to provide ahandleClick
method on the instance itself. So inside the constructor we create ahandleClick
property and assign it’s value toMyComponent
class’s prototype’s handleClick reference but bind it to our instance so we end up to this code:
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
text: "Hello"
};
//----------binding----------
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState({
text: "You clicked!"
});
}
render() {
return (
<div>
<button onClick={this.handleClick}>Click Me</button>
<h1>{this.state.text}</h1>
</div>
);
}
};
And this is what happens after running this.handleClick = this.handleClick.bind(this);
- 7- There’s 3
this
keywords here. Allthis
keywords refer to our instance. First the expression on the right of assignment is run which acceseshandleClick
property on prototype and binds it to our instance, then this reference is assigned intohandleClick
own property.