Many React/React Native beginners are confused by ES6: Most of the advice is to go straight to ES6 syntax (class Foo extends React.Component). However, many tutorials and examples found online are based on the ES5 version, so many people don’t even know what to do when learning. Today in this collation of some ES5 and ES6 writing comparison table, I hope you can read ES5 code, also through comparison, in ES6 to achieve the same function.

The module

reference

In ES5, if the CommonJS standard is used, the React package is introduced via require, and the code looks something like this:

//ES5 var React = require("react-native"); var { Image, Text, PropTypes } = React; // References different React Native componentsCopy the code

In ES6, import is written more standard

//ES6
import React, {
    Image, 
    Text,
    PropTypes
} from 'react-native';
Copy the code

Note that in React Native, the import doesn’t work until 0.12+.

Exporting a single class

In ES5, to export a class to another module, you export it through module.exports

//ES5
var MyComponent = React.createClass({
    ...
});
module.exports = MyComponent;
Copy the code

In ES6, export Default is usually used to implement the same function:

//ES6
export default class MyComponent extends React.Component{
    ...
}
Copy the code

The same goes for quoting:

//ES5
var MyComponent = require('./MyComponent.js');

//ES6
import MyComponent from './MyComponent.js';
Copy the code

Define the components

In ES5, a component class is usually defined through React. CreateClass, like this:

//ES5
var Photo = React.createClass({
    render: function() {
        return (
            ); }});Copy the code

In ES6, we define a component class by defining a class that inherits from React.component.ponent, like this:

//ES6
class Photo extends React.Component {
    render() {
        return (
            ); }}Copy the code

Define methods for components

As you can see from the example above, component methods are no longer written with the name function(), but with the name (), and no commas at the end of the method.

//ES5 
var Photo = React.createClass({
    componentWillMount: function(){

    },
    render: function() {
        return (
            ); }});Copy the code
//ES6
class Photo extends React.Component {
    componentWillMount() {

    }
    render() {
        return (
            ); }}Copy the code

Define the component’s property types and default properties

In ES5, attribute types and default attributes are implemented through the propTypes member and getDefaultProps methods, respectively

//ES5 var Video = React.createClass({ getDefaultProps: function() { return { autoPlay: false, maxLoops: 10, }; }, propTypes: { autoPlay: React.PropTypes.bool.isRequired, maxLoops: React.PropTypes.number.isRequired, posterFrameSrc: React.PropTypes.string.isRequired, videoSrc: React.PropTypes.string.isRequired, }, render: function() { return ( ); }});Copy the code

In ES6, you can implement static members uniformly

//ES6 class Video extends React.Component { static defaultProps = { autoPlay: false, maxLoops: 10, }; / / note that there is a semicolon static propTypes = {the autoPlay: React. PropTypes. Bool. IsRequired, maxLoops: React.PropTypes.number.isRequired, posterFrameSrc: React.PropTypes.string.isRequired, videoSrc: React.PropTypes.string.isRequired, }; Render () {return (); } // Notice that there is neither a semicolon nor a comma}Copy the code

It’s not recommended, but you should know what it means when you read the code:

//ES6
class Video extends React.Component {
    render() {
        return (
            
        );
    }
}
Video.defaultProps = {
    autoPlay: false,
    maxLoops: 10,
};
Video.propTypes = {
    autoPlay: React.PropTypes.bool.isRequired,
    maxLoops: React.PropTypes.number.isRequired,
    posterFrameSrc: React.PropTypes.string.isRequired,
    videoSrc: React.PropTypes.string.isRequired,
};
Copy the code

Note: For React developers, static members cannot be inherited in IE10 and earlier versions, but on IE11 and other browsers, which can sometimes cause problems. React Native developers don’t have to worry about this.

Initialize the state

The situation is similar in ES5,

//ES5 var Video = React.createClass({ getInitialState: function() { return { loopsRemaining: this.props.maxLoops, }; }})Copy the code

Under ES6, there are two ways to write:

//ES6
class Video extends React.Component {
    state = {
        loopsRemaining: this.props.maxLoops,
    }
}
Copy the code

But we recommend the more understandable initialization in the constructor (so you can do some calculations as needed) :

//ES6 class Video extends React.Component { constructor(props){ super(props); this.state = { loopsRemaining: this.props.maxLoops, }; }}Copy the code

Provide methods as callbacks

Many users who are used to ES6 don’t understand that you can do this with ES5:

//ES5
var PostInfo = React.createClass({
    handleOptionsButtonClick: function(e) {
        // Here, 'this' refers to the component instance.
        this.setState({showOptionsModal: true});
    },
    render: function(){
        return (
            
                {this.props.label}
            
        )
    },
});
Copy the code

Under ES5, React. CreateClass will bind all methods so that they can be submitted anywhere as callbacks, and this will not change. But officials are now coming to regard it as non-standard and unintelligible.

Under ES6, you need to bind the this reference through bind or use the arrow function (which binds the this reference to the current scope) to call it

//ES6
class PostInfo extends React.Component
{
    handleOptionsButtonClick(e){
        this.setState({showOptionsModal: true});
    }
    render(){
        return (
            this.handleOptionsButtonClick(e)}
                >
                {this.props.label}
            
        )
    },
}
Copy the code

Arrow function is actually defines a temporary function here, before the arrow arrow function the = > is an empty parentheses, the parameters of a single name, or brackets enclose a multiple parameter names, and after the arrow can be an expression (as a function return values), or with the curly braces enclose a function body (need to return to the return value, Otherwise, undefined is returned.

/ / arrow function example () = = > > 1 v v + 1 (a, b) = > () a + b = > {alert (" foo "); } e=>{ if (e == 0){ return 0; } return 1000/e; }Copy the code

Note that both the bind and arrow functions return a new function reference each time they are executed, so if you need the function reference to do something else (such as uninstall the listener), you must save the reference yourself

/ / wrong class PauseMenu extends React.Com ponent {componentWillMount () {AppStateIOS. AddEventListener (' change ', this.onAppPaused.bind(this)); } componentDidUnmount(){ AppStateIOS.removeEventListener('change', this.onAppPaused.bind(this)); } onAppPaused(event){ } }Copy the code
Class PauseMenu extends React.Com {constructor(props){super(props); // Class PauseMenu extends React.Com {constructor(props){super(props); this._onAppPaused = this.onAppPaused.bind(this); } componentWillMount(){ AppStateIOS.addEventListener('change', this._onAppPaused); } componentDidUnmount(){ AppStateIOS.removeEventListener('change', this._onAppPaused); } onAppPaused(event){ } }Copy the code

We also learned a new practice from this post:

/ / the right thing to do class PauseMenu extends React.Com ponent {componentWillMount () {AppStateIOS. AddEventListener (' change ', this.onAppPaused); } componentDidUnmount(){ AppStateIOS.removeEventListener('change', this.onAppPaused); } onAppPaused = (event) => {// Define the method directly as an arrow function property, which is initialized with this pointer}}Copy the code

Mixins

Under ES5, we often use mixins to add new methods to our classes, such as PureRenderMixin

var PureRenderMixin = require('react-addons-pure-render-mixin');
React.createClass({
  mixins: [PureRenderMixin],

  render: function() {
    return 
       
foo
; }});Copy the code

Mixins Are Dead. Long Live Composition.

Although there are third-party solutions that can be used if mixins are to continue to be used, such as this one

However, the official recommendation for library writers is to abandon mixins as soon as possible. A piece of Sebastian Markbage’s code above suggests a new approach:

//Enhance.js import { Component } from "React"; export var Enhance = ComposedComponent => class extends Component { constructor() { this.state = { data: null }; } componentDidMount() { this.setState({ data: 'Hello' }); } render() { return ; }};Copy the code
//HigherOrderComponent.js import { Enhance } from "./Enhance"; class MyComponent { render() { if (! this.data) return
       
Waiting...
; return
{this.data}
; } } export default Enhance(MyComponent); // Enhanced component Copy the code

An “enhancer” that adds methods to a class and returns a new class undoubtedly fulfills most of the requirements that mixins implement.

Other benefits of ES6+

Deconstruction & attribute extension ###

Combined with the deconstruction and attribute extension of ES6+, it is much easier to pass on a set of attributes to children. This example passes all attributes except className to the div tag:

class AutoloadingPostsGrid extends React.Component { render() { var { className, ... others, // contains all properties of this.props except for className } = this.props; return (
       
Load more
); }}Copy the code

Pass all attributes and override the new className value:


       
...
Copy the code

In this example, on the contrary, the default value is provided if the property does not contain a className, and the value in the property is used if the property already contains one


       
...
Copy the code