Migrating React components to ES6 best practices
React starts with version 0.13 and encourages you to use ES6 to write components. So what do you need to pay attention to when you want to migrate components previously written in createClass to ES6 class definitions? Let me enumerate below, I hope it will be helpful to you.
1. Replacement createClass component is defined as ES6 class definition component
The original way:
var MyComponent = React.createClass({
render: function() {
return <div onClick={this._onClick}>Hello, world.</div>;
},
_onClick: function() {
console.log(this);
}
});
Mode of ES6:
class MyComponent extends React.Component {
render() {
return <div onClick={this._onClick}>Hello, world.</div>;
}
_onClick() {
console.log(this);
}
}
2. Move class attributes such as propTypes, getDefaultTypes to be defined outside the class
Since only defining methods are allowed in ES6 classes and class attributes are not allowed to be defined, component attributes such as propTypes, getDefaultTypes, displayName and contextTypes, which were originally defined in createClass, are assigned outside the class.
The original way:
var MyComponent = React.createClass({
displayName:'MyComponent',
propTypes: {
prop1: React.PropTypes.string
},
getDefaultProps: function() {
return { prop1: '' };
}
});
Mode of ES6:
class MyComponent extends React.Component {...}
MyComponent.displayName = 'MyComponent';
MyComponent.propTypes = {
prop1: React.PropTypes.string
}
MyComponent.defaultProps = {
return { prop1: '' };
}
3. Manually bind class instances to class methods (or callback functions)
The original method created by createClass is bound to the component instances created by it by default. This is actually the grammatical sugar provided by React, but the new version of ES6 is written in such a way that they are no longer provided and you need to bind it manually on demand. If you are interested, you can see their explanations: autobinding
The original way:
var MyComponent = React.createClass({
render: function() {
return <div onClick={this._onClick}>Hello, world.</div>;
},
_onClick: function() {
console.log(this);// Output: MyComponent
}
});
ES6 incorrect way:
class MyComponent extends React.Component {
render() {
return <div onClick={this._onClick}>Hello, world.</div>;
}
_onClick() {
console.log(this); // Output: undefined
}
}
ES6 in the right way:
class MyComponent extends React.Component {
constructor() {
super();
this. _onClick = this. _onClick.bind(this);
}
render() {
return <div onClick={this._onClick}>Hello, world.</div>;
}
_onClick() {
console.log(this); // Output: MyComponent
}
}
Of course, you can also define a tool method in a basic class specifically for binding, and then pass a method name directly in the subclass to achieve, without writing so much repetitive code each time.
4. Move state initialization to constructor
That is, getInitialState definition in ES6 mode will not be valid and will not run at initialization time. You need to move the work in getInitial State to the constructor.
The original way:
class MyComponent extends React.Component {
getInitialState() {
return Store.getState();
}
constructor() {
super();
this. _onClick = this. _onClick.bind(this);
}
}
Mode of ES6:
class MyComponent extends React.Component {
constructor() {
super();
this. _onClick = this. _onClick.bind(this);
this.state = Store.getState();
}
// ...
}