Reputation: 59
For event handlers inside the class component binding is required ( information from lots of sources) . But when console logging the 'this' keyword it logs 'context:undefined' ( because class body is strict as far I know) . And if I console log 'this' inside the event handler ( in this case the changeColor) it logs 'context:{...}' .
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = { color:green};
console.log(this); **// Toggle { ... context:undefined..... }**
this.changeColor = this.changeColor.bind(this);
}
changeColor() {
console.log(this); **// Toggle { ... context:{..} ..... }**
const newColor = this.state.color==green?yellow:green;
this.setState({color:newColor});
}
render() {
return (
<div style={{background:this.state.color}}>
<h1>
Change my color
</h1>
<button onClick={this.changeColor}>
Change color
</button>
</div>
);
}
}
If 'this' is undefined , what are we binding ?
Upvotes: 1
Views: 279
Reputation: 17858
this
should refer to the scope or context of its use. In your case, it's referring to your Component
.
If 'this' is undefined , what are we binding?
Then, you're binding undefined
.
To put it simply, you need this
to access your Component's properties inside your event handler. If you don't need to access them, then you don't need to bind this
.
Consider the following case;
var obj = {
name: 'My Object',
myFunc: function() {
console.log('This object name is', this.name);
}
};
// When `this` is the `obj` itself.
obj.myFunc(); // Prints - "This object name is My Object"
// But, what if the function gets assigned to another variable / context? Which is what event listener does.
var anotherFunc = obj.myFunc;
anotherFunc(); // Prints - "This object name is"
// Since the function will print ANY context.name, we can also do it like;
var anotherFuncButBound = obj.myFunc.bind({
name: 'Something else'
});
anotherFuncButBound(); // Prints - "This object name is Something else"
// In your case, you're doing the following;
var anotherFunc = obj.myFunc.bind(obj);
Upvotes: 0
Reputation: 943564
The changeColor
method depends on this
being the instance of the component (so that when it accesses this.state
it can find it).
You are passing a function to the event listener so it used as a callback.
See How to access the correct this inside a callback?.
If you don't bind the this
value, it will get called in the context of the DOM element when the event handler fires.
Upvotes: 2
Reputation: 167182
This is an old way of doing things. If you don't bind, you won't get to use methods like the following inside the member custom methods like your changeColor()
:
this.setState();
this.props.*;
this.state.*;
And so on. But the new way of declaring things are using () => {}
arrow functions.
Your same code can be rewritten using this way:
class Toggle extends React.Component {
state = { color: green };
changeColor = () => {
const newColor = this.state.color == green ? yellow : green;
this.setState({ color: newColor });
};
render() {
return (
<div style={{ background: this.state.color }}>
<h1>Change my color</h1>
<button onClick={this.changeColor}>Change color</button>
</div>
);
}
}
This way, you don't need a constructor()
or binding this
to functions! To do another reality check, please try this:
import React, { Component } from "react";
export default class App extends Component {
NoArrowFunction() {
console.log(this);
}
ArrowFunction = () => {
console.log(this);
};
render() {
return <div>Check the Console!</div>;
}
}
Upvotes: 0