React React.createClass vs extends React.Component "this" Context

Help us to keep this website almost Ad Free! It takes only 10 seconds of your time:
> Step 1: Go view our video on YouTube: EF Core Bulk Extensions
> Step 2: And Like the video. BONUS: You can also share it!

Example

Using React.createClass will automatically bind this context (values) correctly, but that is not the case when using ES6 classes.

React.createClass

Note the onClick declaration with the this.handleClick method bound. When this method gets called React will apply the right execution context to the handleClick.

import React from 'react';

const MyComponent = React.createClass({
  handleClick() {
    console.log(this); // the React Component instance
  },
  render() {
    return (
      <div onClick={this.handleClick}></div>
    );
  }
});

export default MyComponent;

React.Component

With ES6 classes this is null by default, properties of the class do not automatically bind to the React class (component) instance.

import React from 'react';

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
  }
  handleClick() {
    console.log(this); // null
  }
  render() {
    return (
      <div onClick={this.handleClick}></div>
    );
  }
}

export default MyComponent;

There are a few ways we could bind the right this context.

Case 1: Bind inline:

import React from 'react';

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
  }
  handleClick() {
    console.log(this); // the React Component instance
  }
  render() {
    return (
      <div onClick={this.handleClick.bind(this)}></div>
    );
  }
}

export default MyComponent;

Case 2: Bind in the class constructor

Another approach is changing the context of this.handleClick inside the constructor. This way we avoid inline repetition. Considered by many as a better approach that avoids touching JSX at all:

import React from 'react';

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick() {
    console.log(this); // the React Component instance
  }
  render() {
    return (
      <div onClick={this.handleClick}></div>
    );
  }
}

export default MyComponent;

Case 3: Use ES6 anonymous function

You can also use ES6 anonymous function without having to bind explicitly:

import React from 'react';

class MyComponent extends React.Component {
  constructor(props) {
    super(props);
  }
  handleClick = () => {
    console.log(this); // the React Component instance
  }
  render() {
    return (
      <div onClick={this.handleClick}></div>
    );
  }
}

export default MyComponent;


Got any React Question?