Using ES6 with React - a beginner's overview

ES6 and React feel like shiny new objects. ES6, also known as ECMAScript2015, is the new Ecma standard and has many cool new features. React, created at Facebook, is growing quickly in popularity for good reason-- it's a flexible library that's grounded in reusable view components, one-way data flow, and the virtual DOM.

When combining the two, there are a few sneaky things to be aware of. This post will give you a quick overview of how to make them play nicely together. (And if you’re totally new to React, check out some tutorials before diving in here!)

React.Component

Instead of using React.createClass, ES6 allows you to define React components by instantiating classes that extend React.Component:

class HelloComponent extends React.Component {  
  render() { 
    return (
      <div>Hello, world!</div>
    );
  }
  ...
}

You’ll notice that in doing so, you can define methods with a more compact syntax, dropping the function keyword.

Setting initial state

In forgoing React.createClass, you also lose the getInitialState method. Instead, you call constructor() with super() (more on that here). this.setState is not available within the constructor function, so you’ll have to initialize the state with this.state = {} instead.

Note: some React documentation will say that you should not modify state directly with this.state, but this will be the only way you can access state in the constructor.

class HelloComponent extends React.Component {  
  constructor() {
    super();
    this.state = { showText: true };
  }
  render() { 
    return (
      <div>Hello, world!</div>
    );
  }
  ...
}

Binding component methods

With React.createClass, methods within the class would receive the correct this context. By forgoing that and using React.Component, you'll need to remember to bind your methods within the constructor. If handleClick were not bound in the example below, you would see an error saying "cannot read property setState of undefined".

class HelloComponent extends React.Component {  
  constructor() {
    super();
    this.state = { showText: true };
    this.handleClick = this.handleClick.bind(this);
  }
  render() { 
    return (
      <div onClick={this.handleClick}>Hello, world!</div>
    );
  }
  handleClick() {
    this.setState({ showText: this.state.showText });
  }
}

Note: With ES7, you will be able to simply do this:

handleClick = () => {  
  this.setState({ showText: false });
}

propTypes and defaultProps

To set default props and prop types, you'll have to define them outside of the React Component class. Let's make showText a default prop and pass it through the constructor. Let's also show or hide the text with a ternary operator.

class HelloComponent extends React.Component {  
  constructor(props) {
    super(props);
    this.state = { showText: props.initialShow };
    this.handleClick = this.handleClick.bind(this);
  }
  render() { 
    return (
      { this.state.showText ? <div onClick={this.handleClick}>Hello, world!</div> : <div onClick={this.handleClick}>Goodbye, world!</div> }
    );
  }
  handleClick() {
    this.setState({ showText: !this.state.showText });
  }
}

HelloComponent.propTypes = { initialShow: React.propTypes.bool };  
HelloComponent.defaultProps = { initialShow: true };  

Note: ES7 will allow for a declarative syntax using the keyword static. Take a look here.

Conclusion

Hopefully this gives you a better sense of what to watch out for when using ES6 with React! Refactoring existing code to ES6 could take a lot of work, but moving in that direction allows you to take advantage of all ES6 has to offer. And using Webpack or Gulp with Babel's transpiler allows for a pretty painless development process.

More resources

Babel blog post on React with ES6
Using Webpack + Babel