{"id":31885,"date":"2016-02-02T16:18:50","date_gmt":"2016-02-02T10:48:50","guid":{"rendered":"http:\/\/www.tothenew.com\/blog\/?p=31885"},"modified":"2016-02-02T16:18:50","modified_gmt":"2016-02-02T10:48:50","slug":"building-es6-react-component-from-es5-components","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/building-es6-react-component-from-es5-components\/","title":{"rendered":"Building ES6 React Component from ES5 Components"},"content":{"rendered":"<p>We are in a growing technology world and ES versions are evolving\u00a0very 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\u00a0for how to convert ES5 react components to ES6 components.<\/p>\n<h3>1. Default Props and Prop Types for ES6 React classes<\/h3>\n<p><b>ES5 Version:<\/b><\/p>\n<pre>var UserListComponent = React.createClass({ \r\npropTypes: { \r\n  user: React.PropTypes.object \r\n}, \r\ngetDefaultProps: function() { \r\n  return { user: {} }; \r\n} \r\n});\r\n\r\n<\/pre>\n<p>In ES6 class we can define only methods. So <strong><em>getDefaultProps<\/em><\/strong>\u00a0and\u00a0<strong><em>propTypes<\/em><\/strong>\u00a0are really just properties on the constructor.<br \/>\n<b><b>ES6 Version<\/b>:<\/b><\/p>\n<pre>var UserListComponent = React.createClass({ ... }); \r\nUserListComponent.propTypes = { user: React.PropTypes.object }; \r\nUserListComponent.defaultProps = { user: {} };\r\n\r\n<\/pre>\n<h3>2. How to convert component with createClass to ES6 class<\/h3>\n<p><b><b>ES5 Version<\/b>:<\/b><\/p>\n<pre>var UserListComponent = React.createClass({ \r\n  render: function() { \r\n      return &lt;div&gt;Hello, World! I am a UserList.&lt;\/div&gt;; \r\n  }, \r\n});\r\n<\/pre>\n<p>ES6 components don&#8217;t require &#8216;<em>function<\/em>&#8216; keyword to define methods and commas are also not required to separate each methods.<\/p>\n<p><b><b>ES6 Version<\/b>:<\/b><\/p>\n<pre>class UserListComponent extends React.Component { \r\n   render() { \r\n     return &lt;div&gt;Hello, world! I am a UserList.&lt;\/div&gt;; \r\n   } \r\n}<\/pre>\n<h3>3. How to set initial state in ES6 components<\/h3>\n<p>ES5 components use <strong><em>getInitialState<\/em><\/strong> method to set initial state and this method is invoked once before the component is mounted and return the value of <strong><em>this.state<\/em><\/strong>.<br \/>\nAnd as we are showing a user list so we need to initialize the user list.<\/p>\n<p><b><b>ES5 Version<\/b>:<\/b><\/p>\n<pre>var UserListComponent = React.createClass({ \r\n   getInitialState: function(){ \r\n     return {user: [{name: 'user1', id: 1},{name: 'user2', id: 2}....]} \r\n   } \r\n   render: function() { \r\n      return (&lt;div&gt;Hello, world! I am a UserList.&lt;\/div&gt;; \r\n       this.state.user.map(function(user){ \r\n         return (&lt;div&gt; &lt;h2&gt; {user .name } &lt;\/h2&gt; {user.id} &lt;\/div&gt;); \r\n       }); \r\n    )}, \r\n});<\/pre>\n<p>But in ES6 components, we specify initial state in class <strong><em>constructor<\/em><\/strong>()<br \/>\n<b><b>ES6 Version<\/b>:<\/b><\/p>\n<pre>class UserListComponent extends React.Component { \r\n   constructor(){ \r\n      this.state = {user: [{name: 'user1', id: 1},{name: 'user2', id: 2}....]}    } \r\n   render() { \r\n      return (&lt;div&gt;Hello, world! I am a UserList.&lt;\/div&gt;; \r\n       this.state.user.map(function(user){ \r\n          return (&lt;div&gt; &lt;h2&gt; {user .name } &lt;\/h2&gt; {user.id} &lt;\/div&gt;); \r\n       }); \r\n    )} \r\n}<\/pre>\n<h3>4. How to bind instance methods and callbacks to ES6 class&#8217;s instances<\/h3>\n<p><b><b>ES5 Version<\/b>:<\/b><\/p>\n<pre>class UserListComponent extends React.Component { \r\n   render() { \r\n      return &lt;div onClick={this._handleClick}&gt;Hello, world! I am a UserList.\r\n             &lt;\/div&gt;; \r\n   } \r\n   _handleClick() { \r\n      console.log(this); \/\/ this is undefined \r\n    } \r\n}<\/pre>\n<p>One of the \u00a0best thing about\u00a0ES5 React&#8217;s `<strong><em>createClass<\/em><\/strong>` is\u00a0that methods of components instance automatically bound to instance. As shown in this example, onClick <strong><em>callback(_handleClick )<\/em> <\/strong>would be bound to the component by using `<strong><em>this<\/em><\/strong>`. But while using\u00a0ES6 classes, we must specify this binding ourselves by prebinding in the constructor.<br \/>\n<b><b>ES6 Version<\/b>:<\/b><\/p>\n<pre>class UserListComponent extends React.Component { \r\n   constructor() { \r\n       super(); \r\n       this._handleClick = this. _handleClick.bind(this); \r\n   } \r\n   render() { \r\n      return &lt;div onClick={this._handleClick}&gt;Hello, world! I am a UserList.\r\n             &lt;\/div&gt;; \r\n   } \r\n   _handleClick() { \r\n      console.log(this); \/\/ this is an UserListComponent \r\n   } \r\n}<\/pre>\n<h3>5. Refactor to a base component<\/h3>\n<p><b><b>ES5 Version<\/b>:<\/b><\/p>\n<pre>\u00a0class UserListComponent extends React.Component { \r\n    constructor() { \r\n       super(); \r\n       this._addUser = this._addUser.bind(this); \r\n       this._removeUser = this._removeUser.bind(this); \r\n    } \r\n    \/\/ ... \r\n }<\/pre>\n<p>We can reduce the multiple binding of instance methods to `<strong><em>this<\/em><\/strong>` by writing a `<strong><em>_bind<\/em><\/strong>` method in our `<strong><em>BaseComponent<\/em><\/strong>` constructor. We are using some awesome ES6 features in the `<strong><em>_bind<\/em><\/strong>` method: `<strong><em>methods<\/em><\/strong>` is a\u00a0rest parameter, and\u00a0arrow function\u00a0in the `<strong><em>forEach<\/em><\/strong>`.<br \/>\n<b><b>ES6 Version<\/b>:<\/b><\/p>\n<pre>class BaseComponent extends React.Component { \r\n   _bind(...methods) { \r\n       methods.forEach( (method) =&gt; \r\n         this[method] = this[method].bind(this) ); \r\n    } \r\n} \r\nclass UserListComponent extends BaseComponent { \r\n   constructor() { \r\n      super(); \r\n      this._bind('_addUser', '_removeUser'); \r\n   }\r\n}<\/pre>\n<p>Hope this will help you in converting your ES5 components into ES6 components \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>We are in a growing technology world and ES versions are evolving\u00a0very 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\u00a0for [&hellip;]<\/p>\n","protected":false},"author":810,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":3},"categories":[1],"tags":[3039,3040,3041,4857],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/31885"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/810"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=31885"}],"version-history":[{"count":0,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/31885\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=31885"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=31885"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=31885"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}