What magic "bind" do?

Doing React tutorial and wrote a part of code like this this.toggleChecked(this) instead this.toggleChecked.bind(this) after checkbox go wild (checked -> not checked -> checked -> …loop).

I read about bind, but can’t find any magic in it. Can someone explaine me ??

1 Like

this.toggleChecked.bind(this) means that within your toggleChecked function this refers to the enclosing React Component. For example

class SuperAwesomeComponent extends React.Component {
  ...
  toggleChecked() {
    console.log(this);
  }
  ...
}

Will print undefined to the console for this when toggleChecked is called.

class SuperAwesomeComponent extends React.Component {
  constructor() {
    super();
    this.toggleChcked = this.toggleChecked.bind(this);
  }
  ...
  toggleChecked() {
    console.log(this);
  }
  ...  
}

Will show that this refers to the enclosing SuperAwesomeComponent instead of being undefined.

If you were using React.createClass before you didn’t need to worry about this as React took care of it. They decided to stop doing this with ES2015 class support (and explain why here).

As to why your app crashed when you passed this in as a parameter instead of binding it, there could be a few reasons (we’d need to see your toggleChecked code to verify).

There’s no ‘magic’ as such - it’s a native function property available on other declared functions like toggleChecked which sets the function’s context to the first argument (this).

It can also be used to define pre-determined arguments:

let foo = 'Hello, ';
let bar = 'world!'

const doSomething = function (foo, bar) {
  console.log(foo, bar);
}

doSomething.bind(this, foo);

doSomething(bar); // prints Hello, world!


Great detailed explanation here: http://reactkungfu.com/2015/07/why-and-how-to-bind-methods-in-your-react-component-classes/

The reason for the weird checkbox behaviour is because every time your component renders, it immediately calls toggleChecked(this) which triggers your component to re-render and call it again in an infinite loop.

Using .bind() on the other hand, doesn’t call/invoke the function, it instead returns the bound version.

.bind(context-to-bind) is a standard JavaScript Function Object method that returns a new function with it’s invocation context ‘this’ bound to the value you provided: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind

In your example/tutorial, when the render() method of your React Component class is called it returns the JSX having first evaluated it. The ‘this.toggleChecked.bind(this)’ part of ‘onClick={this.toggleChecked.bind(this)}’ returns the ‘this.toggleChecked’ method with it’s invocation context (‘this’) now bound to the ‘this’ that you passed with the .bind() method. The binding cannot be overridden.

In JavaScript/ECMAScript the invocation context (‘this’) is the current context when the function is invoked, not when it is defined/declared. This means that the React Component class may not be available to the function at the time it was invoked even though you declared it from within it.

Using .bind(this) therefore ensure that the invocation context ‘this’ is always bound to the method, which can then access it via ‘this’.

‘this.toggleChecked(this)’ is invoking a method every time the render() method is invoked, which is then changing data and causing a re-rendering, hence the rendering loop. The .bind() method returns the function instead to be invoked later via user event (onClick);