In the following example I'm trying to better understand the bind method. Specifically, what do the two instances of 'this' refer to and why do we need the second one? Also, why don't I need to include 'this' in the callback:
UPDATE:
I understand now that they both refer to FontChooser but why do we want to bind FontChooser.checkbox to FontChooser? Isn't that redundant? or in other words if 'this' refers to the class why do we need to bind a class callback (this.checkbox) to the class (this.checkbox.bind(this))?
It's almost like we are binding a specific instance back to the class callback but (a) where are we creating the specific instance and (b) shouldn't the specific instance already have the class callback
class FontChooser extends React.Component {
constructor(props) {
super(props);
this.state = {
hidden: true,
checked: this.props.bold ? true : false
};
}
displayButtons() {
this.setState({
hidden: !this.state.hidden
});
}
checkbox() {
//why not checkbox(this){
this.setState({ checked: !this.state.checked });
}
render() {
console.log(this.state);
var weight = this.state.checked ? "bold" : "normal";
return (
<div>
<input
type="checkbox"
id="boldCheckbox"
hidden={this.state.hidden}
checked={this.state.checked}
onChange={this.checkbox.bind(this)}
/>
<button id="decreaseButton" hidden={this.state.hidden}>
{" "}
-{" "}
</button>
<span id="fontSizeSpan" hidden={this.state.hidden}>
{" "}
{this.state.size}
</span>
<button id="increaseButton" hidden={this.state.hidden}>
{" "}
+{" "}
</button>
<span
id="textSpan"
style={{ fontWeight: weight, fontSize: this.state.size }}
onClick={this.displayButtons.bind(this)}
>
{" "}
{this.props.text}
</span>
</div>
);
}
}
In javascript, the this
keyword points to a different object depending on the context it was executed in. When using a function in the JSX 'template', the function is not executed within your class, but in some other context in React. As a consequence, whatever this
refers to, is changed.
One was to work around this, is using the bind()
method. This method will replace whatever function it is used on, and replace whatever the this
keyword points to, to a new location you provided.
In your example, you're using this.displayButtons.bind(this)
. Here, this
refers to this class (FontChooser
), and will make sure that this
will point to that class regardless of the execution context.
Take a look at the MDN documentation, there are also easy to understand examples. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind