Why do we need to use bind for events in class based components?

You might be wondering why you need to use bind() for calling class methods from events in React. Maybe you’ve just chucked the binds in and it works, so move on: if it ain’t broke don’t fix it. Even so, you might have a nagging feeling because you don’t know why you need these, and in programming if you don’t know why you are writing the code … well that is going to come and bite you later on!

Here is an example taken from the React docs, with a bind statement in the constructor, and a thoughtful but slightly mysterious comment as to why this was done:

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>
    );
  }
}

So what would happen if you didn’t have the following magic line?

    this.handleClick = this.handleClick.bind(this);

This line does a lot of things at once. If you are interested, it is doing all of this. If you are a beginner don’t worry too much about understanding all of this now.

  • It gets the current object instance using this – which we can trust because we are in the constructor so it has to be the object instance and not something else.
  • It passes that object instance to the bind method, which takes the function handleClick and returns a function which does exactly the same thing, but with this fixed inside that function to the object instance.
  • Finally it assigns this new function to replace the existing handleClick, so that whenever this is called and from where-ever it is called, it uses the object instance and not some other value as this.

That’s a lot of stuff, but in a nutshell it is forcing handleClick to always use the object instance as the value for this regardless of how the function is called.

The reason this is all needed is because in the render:

<button onClick={this.handleClick}>

This is JSX code and gets compiled into plain JavaScript. This plain Javascript will save a reference to the this.handleClick method to be called later when it is clicked. When that method is called it is not being called from render() but from inside React somewhere, and without the bind, the this keyword would have some other value that w don’t want.

It’s worth revisiting the rules of how the this value is calculated from time to time. It’s not too intuitive and easy to forget if you haven’t looked at it for a while. For JavaScript topics, Mozillas, documentation is very good, and here is there documentation on this, so check that out, and importantly have a play with some code to make sure you understand it. I think the way this works is an unfortunate source of confusion in JavaScript but it’s the way it is, and unlikely to ever change!

Posted by Martin Capodici

.

Leave a Comment

Your email address will not be published. Required fields are marked *