ReactJS gives us the opportunity to use ES7+ features early enough because of its very nature. By using a compiler like Babel we can even start using experimental ones and master upcoming JavaScript characteristics before they get officially released. This is extremely beneficial and makes us hell better developers since we can track closely language’s evolution. In my opinion, this adaptability is one of the most powerful features of ReactJS.

Stateful Components

In order to create a stateful component, we can use an ES6 class by extending React.Component:

ES6 classes allow us to initialize state in the constructor and make bindings with props. Using a getter method like getInitialState() is not needed anymore.

Stateless Components

For stateless components we can use an arrow function:

Things are quite simple here and we can destructure props in order to make things even more clear.

Spread Operator & Attributes

Above we destructured props so now we know that in UserItem component user prop is passed and this is the only one we need. What if we want to make this more extendable and add some others props like className or even inline styling? Right now even if we pass a className up there as a prop it won’t get rendered in our component because we have specified clearly that we are waiting just for user prop.

How can we fix this? We can take advantage of spread attributes by using spread operator:

That’s it. Now apart from user prop we can pass as many props as we like and they will get rendered in the wrapping div tag. In real world there are times we don’t really know all props we might need to pass in there. What if we want to pass some inline styling with: style = {{marginTop: ‘50px’}} or we need to add a className? Now with that …restProps in there we are good to go.

In an enterprise application this will make our codebase messy and less maintainable, if we apply this pattern globally. I would recommend to pass specifically className as a prop and leave that …restProps in there just for cases you might need inline styling. If not you better drop it. It is far more preferable if you specify exactly all props you need while destructuring. If you cannot do this and you feel you simply need more then use that spread operator but do it sparingly.

Property initializers

We used before the constructor to initialize state but we can make it even better by using Property initializers. This is a new feature at stage-2 (March of 2017) so we need preset stage-2 in our .babelrc. Let’s check how we can use them in our stateful components:

As you see we don’t need to use class’ constructor anymore. Property initializers are bound to the class instance and they are not on the prototype. This means that this.state exists while UserItem.prototype.state is undefined. They operate inside the constructor so keyword this is available to make bindings with props values.

Static class properties

By using Static class properties we can bind some properties with the class’ prototype. These are perfect to declare defaultProps and propTypes:

It is obvious that using a getter like getDefaultProps() is not needed anymore.

Arrow functions

When we use ES6 classes to declare our components it is quite common to make manually instance bindings in the constructor so that this keyword inside events handlers methods refers to class itself:

By taking advantage of property initializers we can use arrow functions to achieve that binding without making all these redundant bindings into the constructor:

Decorators

Decorators are widely used across modern coding languages but are not natively supported by JavaScript yet. Right now they are at stage-2. Babel 6 offers Legacy Decorator plugin babel-plugin-transform-decorators-legacy if we want to use them in our codebase.

A famous npm package is named core-decorators so we will install it and then use @autobind decorator in our next example. This method is perfect to achieve instance bindings across our event handlers:

Pretty clean right? Now keyword this inside onClick method refers to class itself. If we are lazy we can apply this to the parent class and this will take care of all methods inside of it: