This is an article by Steven Luscher about React, Steven Luscher is good at building apps using React and GRAPHQL.
Original address:http://babeljs.io/blog/2015/06/07/react-on-es6-plus/
When you redesigned the Instagram Web, some es6+ features were used to write the React component. Here's a brief look at the implications of these new language features for the development of React applications, which make React development simpler and more interesting.
Class
So far, the best embodiment of our use of es6+ to write React components is that we chose to use the class definition syntax. Instead of using React.createClassmethods to define a component, we can define a bonafide ES6 class to extendReact.Component:
class Photo extends React.Component {
Render () {
return <img alt={this.props.caption} src={this.props.src} />;
}
}
Now, you'll find a subtle difference - the syntax is simpler when defining classes:
// The ES5 way
var Photo = React.createClass({
handleDoubleTap: function(e) { … }
render: function() { … }
};
// The ES6+ way
class Photo extends React.Component {
handleDoubleTap(e) { … }
render() { … }
}
It is worth noting that we have removed two parentheses and a semicolon, and each method declaration omits a colon, a keyword and a semicolon.
When you use a new class definition, at least one of the lifecycle methods meets your expectations. The constructor of the class now assumes that role was previously filled through componentwillmount:
// The ES5 way
var EmbedModal = React.createClass({
componentWillMount: function() { … }
};
// The ES6+ way
class EmbedModal extends React.Component {
constructor(props) {
super(props);
// Operations usually carried out in componentWillMount go here
}
}
Property initializer
In the world of ES6 + classes, prop types and defaults live are static properties in the class itself. These are the same in the initialization state of components. You can use ES7 property initializers to define:
// The ES5 way
var Video = React.createClass({
getDefaultProps: function() {
Return {
autoPlay: false,
maxLoops: 10,
}
}
getInitialState: function() {
Return {
loopsRemaining: this.props.maxLoops,
}
}
PropTypes: {
autoPlay: React.PropTypes.bool.isRequired,
maxLoops: React.PropTypes.number.isRequired,
posterFrameSrc: React.PropTypes.string.isRequired,
videoSrc: React.PropTypes.string.isRequired,
}
};
// The ES6+ way
class Video extends React.Component {
static defaultProps = {
autoPlay: false,
maxLoops: 10,
}
static propTypes = {
autoPlay: React.PropTypes.bool.isRequired,
maxLoops: React.PropTypes.number.isRequired,
posterFrameSrc: React.PropTypes.string.isRequired,
videoSrc: React.PropTypes.string.isRequired,
}
State = {
loopsRemaining: this.props.maxLoops,
}
}
The ES7 property initializer operates the constructor of the inner class. This refers to the class instance of the construction, so the initialization state can depend on this.props. It's worth noting that we no longer define the default value of prop and use the getter function to initialize the state object.
Arrow function
The react.createclass method is used to perform some additional binding work in your component instance method. To ensure that this keyword points to the component instance:
// Autobinding, brought to you by React.createClass
var PostInfo = React.createClass({
handleOptionsButtonClick: function(e) {
// Here, ‘this‘ refers to the component instance.
this.setState({showOptionsModal: true});
}
};
Since we do not participate in the react.createclass method, but use the ES6 + class syntax to define components, it seems that we need to manually bind instance methods:
// Manually bind, wherever you need to
class PostInfo extends React.Component {
constructor(props) {
super(props);
// Manually bind this method to the component instance...
this.handleOptionsButtonClick = this.handleOptionsButtonClick.bind(this);
}
handleOptionsButtonClick(e) {
// ...to ensure that ‘this‘ refers to the component instance here.
this.setState({showOptionsModal: true});
}
}
Fortunately, by binding two ES6 + features - arrow functions and property initializer - you can choose to bind component instances:
class PostInfo extends React.Component {
handleOptionsButtonClick = (e) => {
this.setState({showOptionsModal: true});
}
}
The arrow function body of ES6 shares the same word this, which is used to surround their code, which can achieve our expected results, and is also the way that the ES7 attribute initializer is in the domain. Peek under the hood to see why.
Dynamic property name & template string
One of the object constant enhancements is that you can assign to a derived property name. We may initially set some states as follows:
var Form = React.createClass({
onChange: function(inputName, e) {
var stateToSet = {};
stateToSet[inputName + ‘Value‘] = e.target.value;
this.setState(stateToSet);
}
};
Now, we have the ability to construct an object that determines the name of a property through a runtime JavaScript expression. Here, we use a template string to determine which property set state:
class Form extends React.Component {
onChange(inputName, e) {
this.setState({
[`${inputName}Value`]: e.target.value,
};
}
}
Deconstruction & propagation attribute
Usually when writing components, we may want to pass props of most of the parent components to the child components, but not all of them. Combined with ES6 + deconstruction and JSX propagation properties, this part can be implemented without extra parts:
class AutoloadingPostsGrid extends React.Component {
Render () {
Var {
ClassName,
...others, // contains all properties of this.props except for className
} = this.props;
Return (
<div className={className}>
<PostsGrid {...others} />
<button onClick={this.handleLoadMoreClick}>Load more</button>
</div>
);
}
}
We can use a simple priority principle to implement overrides and defaults by combining JSX propagation attributes and general attributes. This element requires that the classname "override" even exists in this.props:
<div {...this.props} className="override">
...
</div>
Generally speaking, this element requires classname "base", unless this.props has the classname attribute override:
<div className="base" {...this.props}>
...
</div>
I hope you can enjoy some of the convenience that ES6 + language features bring to react development.
Develop react components with ES6 +