Building ES6 React Component from ES5 Components

02 / Feb / 2016 by Mahima Agrawal 0 comments

We are in a growing technology world and ES versions are evolving very fast. I was working in a react project with ES5 but we had to revamp our ES5 components into ES6 components and I have faced so many problems at each point. So in this blog I am trying to cover some basic steps for how to convert ES5 react components to ES6 components.

1. Default Props and Prop Types for ES6 React classes

ES5 Version:

var UserListComponent = React.createClass({ 
propTypes: { 
  user: React.PropTypes.object 
}, 
getDefaultProps: function() { 
  return { user: {} }; 
} 
});

In ES6 class we can define only methods. So getDefaultProps and propTypes are really just properties on the constructor.
ES6 Version:

var UserListComponent = React.createClass({ ... }); 
UserListComponent.propTypes = { user: React.PropTypes.object }; 
UserListComponent.defaultProps = { user: {} };

2. How to convert component with createClass to ES6 class

ES5 Version:

var UserListComponent = React.createClass({ 
  render: function() { 
      return <div>Hello, World! I am a UserList.</div>; 
  }, 
});

ES6 components don’t require ‘function‘ keyword to define methods and commas are also not required to separate each methods.

ES6 Version:

class UserListComponent extends React.Component { 
   render() { 
     return <div>Hello, world! I am a UserList.</div>; 
   } 
}

3. How to set initial state in ES6 components

ES5 components use getInitialState method to set initial state and this method is invoked once before the component is mounted and return the value of this.state.
And as we are showing a user list so we need to initialize the user list.

ES5 Version:

var UserListComponent = React.createClass({ 
   getInitialState: function(){ 
     return {user: [{name: 'user1', id: 1},{name: 'user2', id: 2}....]} 
   } 
   render: function() { 
      return (<div>Hello, world! I am a UserList.</div>; 
       this.state.user.map(function(user){ 
         return (<div> <h2> {user .name } </h2> {user.id} </div>); 
       }); 
    )}, 
});

But in ES6 components, we specify initial state in class constructor()
ES6 Version:

class UserListComponent extends React.Component { 
   constructor(){ 
      this.state = {user: [{name: 'user1', id: 1},{name: 'user2', id: 2}....]}    } 
   render() { 
      return (<div>Hello, world! I am a UserList.</div>; 
       this.state.user.map(function(user){ 
          return (<div> <h2> {user .name } </h2> {user.id} </div>); 
       }); 
    )} 
}

4. How to bind instance methods and callbacks to ES6 class’s instances

ES5 Version:

class UserListComponent extends React.Component { 
   render() { 
      return <div onClick={this._handleClick}>Hello, world! I am a UserList.
             </div>; 
   } 
   _handleClick() { 
      console.log(this); // this is undefined 
    } 
}

One of the  best thing about ES5 React’s `createClass` is that methods of components instance automatically bound to instance. As shown in this example, onClick callback(_handleClick ) would be bound to the component by using `this`. But while using ES6 classes, we must specify this binding ourselves by prebinding in the constructor.
ES6 Version:

class UserListComponent extends React.Component { 
   constructor() { 
       super(); 
       this._handleClick = this. _handleClick.bind(this); 
   } 
   render() { 
      return <div onClick={this._handleClick}>Hello, world! I am a UserList.
             </div>; 
   } 
   _handleClick() { 
      console.log(this); // this is an UserListComponent 
   } 
}

5. Refactor to a base component

ES5 Version:

 class UserListComponent extends React.Component { 
    constructor() { 
       super(); 
       this._addUser = this._addUser.bind(this); 
       this._removeUser = this._removeUser.bind(this); 
    } 
    // ... 
 }

We can reduce the multiple binding of instance methods to `this` by writing a `_bind` method in our `BaseComponent` constructor. We are using some awesome ES6 features in the `_bind` method: `methods` is a rest parameter, and arrow function in the `forEach`.
ES6 Version:

class BaseComponent extends React.Component { 
   _bind(...methods) { 
       methods.forEach( (method) => 
         this[method] = this[method].bind(this) ); 
    } 
} 
class UserListComponent extends BaseComponent { 
   constructor() { 
      super(); 
      this._bind('_addUser', '_removeUser'); 
   }
}

Hope this will help you in converting your ES5 components into ES6 components :-)

FOUND THIS USEFUL? SHARE IT

Leave a comment -