Click here to Skip to main content
15,887,214 members
Articles / All Topics

React: ES5 (createClass) or ES6 (class)?

Rate me:
Please Sign up or sign in to vote.
4.00/5 (1 vote)
14 Jun 2016CPOL3 min read 7.1K   1  
React: ES5 (createClass) or ES6 (class)?

When writing React, should you use the React.createClass syntax or the ES6 class syntax? Or maybe neither? This post will explain some of the differences and help you decide.

React can be written perfectly well in either ES5 or ES6.

Using JSX means that you’ll need a “build” step already, where Babel transpiles the JSX into React.createElement calls. Many people take advantage of this and just tack on es2015 to Babel’s list of transpilers, and then the entire world of ES6 is made available.

If you’re using something like Quik or React Heatpack, this is already set up for you (read quick start React if you don’t have an environment, set up yet).

Compare: createClass vs class

Here’s the same component written using React.createClass and ES6 class:

JavaScript
var InputControlES5 = React.createClass({
  propTypes: {
    initialValue: React.PropTypes.string
  },
  defaultProps: {
    initialValue: ''
  },
  // Set up initial state
  getInitialState: function() {
    return {
      text: this.props.initialValue || 'placeholder'
    };
  },
  handleChange: function(event) {
    this.setState({
      text: event.target.value
    });
  },
  render: function() {
    return (
      <div>
        Type something:
        <input onChange={this.handleChange}
               value={this.state.text} />
      </div>
    );
  }
});
JavaScript
class InputControlES6 extends React.Component {
  constructor(props) {
    super(props);

    // Set up initial state
    this.state = {
      text: props.initialValue || 'placeholder'
    };

    // Functions must be bound manually with ES6 classes
    this.handleChange = this.handleChange.bind(this);
  }
  
  handleChange(event) {
    this.setState({
      text: event.target.value
    });
  }
  
  render() {
    return (
      <div>
        Type something:
        <input onChange={this.handleChange}
               value={this.state.text} />
      </div>
    );
  }
}
InputControlES6.propTypes = {
  initialValue: React.PropTypes.string
};
InputControlES6.defaultProps = {
  initialValue: ''
};

Here are the key differences:

Binding of Functions

This is probably the biggest tripping point.

With createClass, it’s easy: every property that’s a function is automatically bound by React. Refer to them as this.whateverFn wherever you need to, and this will be set correctly whenever they’re called.

With ES6 class, it’s trickier: functions are not autobound. You must manually bind them. The best place to do this is in the constructor, as in the example above.

If you want to save yourself from having to type out all those bindings manually, check out react-autobind or autobind-decorator.

An alternative way is to bind them inside the render method or using the ES6 arrow function:

JavaScript
// Use `.bind`:
render() {
  return (
      <input onChange={this.handleChange.bind(this)}
             value={this.state.text} />
  );
}

// --- OR ---

// Use an arrow function:
render() {
  return (
      <input onChange={() => this.handleChange()}
             value={this.state.text} />
  );
}

Either of these will work, but they’re not as efficient. Every time render is called (which could be pretty often!) a new function will be created. It’s a little slower than binding the functions once in the constructor.

Constructor Should Call super

The ES6 class’s constructor needs to accept props as an argument and then call super(props). It’s a little bit of boilerplate that createClass doesn’t have.

class vs createClass

This one is obvious. One calls React.createClass with an object, and the other uses class extending React.Component.

Pro tip: Import Component directly to save some typing if you have multiple components in one file: import React, {Component} from 'react'.

Initial State Configuration

createClass accepts an initialState function that gets called once when the component is mounted.

ES6 class uses the constructor instead. After calling super, set the state directly.

Location of propTypes and defaultProps

With createClass, define propTypes and defaultProps as properties on the object you pass in.

With ES6 class, these become properties of the class itself, so they need to be tacked on to the class after it is defined.

There’s a shortcut if your build has ES7 property initializers turned on:

JavaScript
class Person extends React.Component {
  static propTypes = {
    name: React.PropTypes.string,
    age: React.PropTypes.string
  };

  static defaultProps = {
    name: '',
    age: -1
  };

  ...
}

The Ninja Third Option

In addition to createClass and class, React also supports what it calls “stateless functional components.” Basically, it’s just a function, and it can’t have state, and it can’t use any of the lifecycle methods like componentWillMount or shouldComponentUpdate. Stateless functional components are great for simple components when all they do is take some props and render something based on those props. Here’s an example:

JavaScript
function Person({firstName, lastName}) {
  return (
    <span>{lastName}, {firstName}</span>
  );
}

That uses ES6 destructuring to pull apart the props that are passed in, but it could also be written like this:

JavaScript
function Person(props) {
  var firstName = props.firstName;
  var lastName = props.lastName;
  return (
    <span>{lastName}, {firstName}</span>
  );
}

Which is the Right One to Use?

It comes down to a mix of personal preference, and asking yourself which is the right tool for the job.

For simple components, stick to stateless functional ones.

For more complex components that need state, lifecycle methods, or access to the underlying DOM nodes (through refs), you’ll need to use either createClass or class.

It’s good to know all 3 styles. When it comes time to look up a problem on StackOverflow or elsewhere, you’ll probably see answers in a mix of ES5 and ES6, though the ES6 style is gaining in popularity lately.

Wrap Up

I hope this overview helped clear up some confusion about the different ways to write components in React.

If you’re feeling overwhelemed by all there is to learn, and looking for a path to follow, sign up below to get a downloadable Timeline for Learning React.

React: ES5 (createClass) or ES6 (class)? was originally published by Dave Ceddia at Angularity on June 14, 2016.

This article was originally posted at https://daveceddia.com/feed.xml

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
Dave is a Software Engineer in the Boston area and writes about AngularJS and other JavaScript things over at daveceddia.com

Comments and Discussions

 
-- There are no messages in this forum --