-1

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>
    );
  }
}
DCR
  • 14,737
  • 12
  • 52
  • 115
  • The first argument to `.bind` is the value to use as `this`. Any other arguments will be passed to the method as additional parameters when you call the bound function. – Dan Prince Dec 01 '19 at 17:13

1 Answers1

1

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

Celsiuss
  • 895
  • 7
  • 19
  • so the first 'this' associates the checkbox callback with the class and the 'this' inside of .bind('this') gives the callback access to state and props. Is that correct? – DCR Dec 01 '19 at 17:30
  • When you're using `this` within a class, in most cases `this` will refer to this class instance. Taking a look at `this.displayButtons.bind(this)`, here you want to execute the `displayButtons()` method on this class instance, and that's why you're using `this`. The second `this` inside the `bind()` method makes sure that whenever `this` is used inside your method, it will always refer to your class instance regardless of the execution context. – Celsiuss Dec 01 '19 at 17:38
  • And yes, that will give your method access to the state and props, since that is a part of your class instance. – Celsiuss Dec 01 '19 at 17:39