I was reading the documentation and practicing some things in the React documentation until I finally entered the event handling section. but I don't understand why when using method in class component we have to bind the function, can anyone explain it? for examples :
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
// This binding is necessary to make `this` work in the callback
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(prevState => ({
isToggleOn: !prevState.isToggleOn
}));
}
render() {
return (
<button onClick={this.handleClick}>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
}
CodePudding user response:
The point is to keep correct value of this
reference. Check this example:
class Example {
private prop = 1;
echoProp() {
console.log(this?.prop);
}
}
const example = new Example();
example.echoProp();
const echoPropRef = example.echoProp;
echoPropRef();
In the console you will see 1
and then undefined
. This is because:
Example:echoProp
'sthis
reference is instance ofExample
class, so it see alsoprop
property.- if you pass
Example:echoProp
's reference to another variable (const echoPropRef = example.echoProp
- there is no()
), thenthis
reference is changed intoundefined
.
bind
function "freezes" this
reference, so it will be always the same; in you example it will be reference to Toggle
class.
The bind
is necessary if you use code like
<button onClick={this.handleClick}>
CodePudding user response:
When handleClick
is triggered by the button, this
value inside handleClick
will be the click event (this is js behaviour for event listener), but the click event does not have a setState
method, which belongs to the component itself. So you want to bind the method to the component, so that this
value inside handleClick
will be the Toggle
component which has the setState
method
CodePudding user response:
The this
is problem is a general problem in JS (not limited to React).
Normally inside a method, this
refers to the current object instance.
Inside an event listener (even if its a method), this
refers to the event target.
The this
in this.setState
must refer to the Component instance.
So to change the value of this
, binding is done in the constructor.
Another solution would be
onClick={(evt)=>{handleClick(evt)}}
In this case handleClick
ceases being an event listener and the actual event listener would be the anonymous function inside onClick
.
The simplest alternative is :
handleClick=(evt)=>{
this.setState(...)
}
Arrow functions do not have their own this
& hence acquire the current object (component) instance as this
.