Binding ES Class Methods in React

Working with this can be confusing in React, especially when React has multiple ways to build components. Let's look the few ways to deal with this.

The choice between using the ES class method for declaring component in React seems to be a decided convention within the React community. The only issue with it the need to bind the context of this everytime you create a function. This way you have

The Netlify login form is an easy enough component to look at:

class LoginPage extends React.Component {
  constructor(props) {
    super(props);
    this.state = {loginError: null};
  }

  onLogin(provider) {
    return (event) => {
      // ...
    };
  }

  render() {
    const login = () => this.onLogin.bind;
    return <LoginForm handleLogin={login} loginError={this.state.loginError}/>;
  }
}

Everytime you need to use a class function you have two options:

return <LoginForm handleLogin={this.onLogin.bind(this)} loginError={this.state.loginError}/>;

This option will not pass the default eslint settings, due the unpopular use of bind in jsx.

const login = () => this.onLogin
return <LoginForm handleLogin={login} loginError={this.state.loginError}/>;

The problem here is the need to create a separate function to gain access to the lexically scoped this. This will create a new function object every time render is called

A new way to handling the the binding of class methods do this has arisen and it’s actually pretty nice. Just add the bind(this) to the class’s constructor.

constructor(props) {
  super(props);
  // ...
  this.onLogin = this.onLogin.bind(this);
}

Now you can call just call this.onLogin directly, which save a bit of typing and maybe a kilobyte or two in minification.

class LoginPage extends React.Component {
  constructor(props) {
    super(props);
    // ...
    this.onLogin = this.onLogin.bind(this);
  }

  onLogin(provider) {
    return (event) => {
      // ...
    };
  }

  // this.onLogin will now just use the function defined
  // in the constructor no need to create a whole new function

  render() {
    const login = () => this.onLogin.bind;
    return <LoginForm handleLogin={this.onLogin} loginError={this.state.loginError}/>;
  }
}

How do you handle binding class methods in React, what are your thoughts?

*Update: There is a great discussion on some alternative solutions to this problem here

For a better understanding on this in JavaScript, check out the article Gentle explanation of ‘this’ keyword in JavaScript