Saturday, 9 April, 2016 UTC


Summary

I've been meaning to do this for a while, but we finally ported all our React code to ES6 classes. The migration was pretty simple, but I figured sharing my notes might help someone out there.

Class creation

We had been using React.createClass, but with ES6 this changes to extends React.Component.
Old
const Widget = React.createClass({  
   // code is here
});
New
class Widget = extends React.Component {  
   // code is here
}

PropTypes

PropTypes are no longer part of the code within the class. They are defined afterwards.
Old
const Widget = React.createClass({

  propTypes: {
    fn: React.PropTypes.func,
    thing: React.PropTypes.object
  }

});
New
class Widget = extends React.Component {  
   // code is here
}

Widget.propTypes: {  
  fn: React.PropTypes.func,
  thing: React.PropTypes.object
};

Initial State

Initial state is now set in the constructor.
Old
const Widget = React.createClass({

  getInitialState() {
    return {
      foo: 'bar'
    };
  }

});
New
class Widget = extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      foo: 'bar'
    };
  }

}

Function Binding

You might not know, but React does some magic internally when you use createClass. This includes auto-binding this to your functions. If you have a function that needs access to the component, you now need to bind it in the constructor.
Old
const Widget = React.createClass({

  doSomeWork() {
     return this.props.foo;
  }

});
New
class Widget = extends React.Component {

  constructor(props) {
    super(props);
    this.doSomeWork = () => this._doSomeWork();
  }

  _doSomeWork() {
     return this.props.foo;
  }

}

Other issues

Mixins are not supported in ES6. Most libraries are already moving away from them. We did have to update react-router and react-intl.
Happy porting and welcome to ES6!