ES6 classes as React components
The upcoming JavaScript standard, commonly referred to as ES6, will introduce a new syntax to define classes. With React 0.13, you can do without React.createClass
and define components with plain functions. You can use ES6 classes to smooth the component definition process. Let’s see how it works.
The React functionality is available in the 0.13 beta. Of course, ES6 classes are not implemented in any browser yet, so you will need a transpiler. Luckily, react-tools
, the same tool that you use to compile JSX, can also handle ES6 classes. The only thing you need to change in your build to use the --harmony
flag if you didn’t already.
The first thing you’ll notice is that JavaScript class definitions have a different syntax than objects: you do not use a colon and the function
keyword to declare member functions; instead, you just write the function name followed by the its body:
class Button {
render() {
return <button>{this.props.number}</button>
}
}
You can also use the extends
keyword to inherit from a base class. This is classic JavaScript prototypical inheritance, so in a sense, ‘class’ is a misnomer.
class Button extends React.Component {
render() {
return <button>{this.props.number}</button>
}
}
It is strictly equivalent to
var Button = function() {React.Component.apply(this, arguments)}; // run parent 'constructor'
Button.prototype = Object.create(React.Component.prototype); // copy parent prototype
Button.prototype.render = function() { // define methods
return <button>{this.props.number}</button>
}
Button.prototype.constructor = Button; // make 'constructor' point to the right function
ES6 classes just add more a concise way to achieve something that could be already done. In this case, we do not even need to inherit from React.Component
, since Button
is probably stateless. The more significant change lies in React itself.
React has been refactored to be able to use any function that can construct an object as the basis for a component. A stateful component, though, needs to call setState
when its internal state changes. React 0.13 also introduces React.Component
, that you can use to ‘inherit’ the setState
function as needed.
class Calculator extends React.Component {
constructor() {
this.state = {result: 0};
}
}
Name a member function constructor
and it will run when the object is created: putting code inside constructor
is the same as putting it into the body of the Calculator
function if you defined ‘classes’ with the classic method. The end result will be equivalent to this code:
var Calculator = function() {
React.Component.apply(this, arguments);
this.state = {result: 0};
};
Calculator.prototype = Object.create(React.Component.prototype);
Calculator.prototype.render = function() {
return <input type="text" value={this.state.result}/>;
}
Calculator.prototype.constructor = Calculator;
var myCalculator = new Calculator(); // this points to myCalculator
Now Calculator has a setState()
method because setState
is defined on React.Component
’s prototype
. In a React 0.13 app, we can use constructors to replace getInitialState()
, as we are doing in this Calculator
class to set the initial display to 0.
React 0.13 will allow more generic mechanisms to define components. ES6 classes are (mostly!) syntactic sugar.