我的 React Native 技能树点亮计划 の React Native 从 ES5 到 ES6 的语法升级

@author ASCE1885的 Github 简书 微博 CSDN 知乎 本文由于潜在的商业目的,不开放全文转载许可,谢谢!

0?wx_fmt=png

ECMAScript 2015(为了行文简短起见,后文统称为 ES6)已经于 2015 年 6 月份正式发布,React 框架从 v0.13[1] 版本开始增加对 ES6 语法的支持,React Native 框架从 v0.18.0 版本开始,例子工程 AwesomeProject 的index.android.js 和 index.ios.js 中的语法也由之前版本的 ES5 语法切换到 ES6 语法。虽然官方没有明确说不鼓励 ES5 语法,但使用 ES6 代替 ES5 是大势所趋,为何不就现在开始做呢?在新开发的代码中,我们建议尽量使用 ES6 语法。下面就来具体说说 React Native 开发中哪些方面涉及到 ES5 语法到 ES6 语法的升级。

模块的导入

在 ES5 语法中,模块的导入使用 require 语句,到了 ES6 则改用 import 语句,先来看下 ES5 语法:

let React = require('react-native');	
let {	
    AppRegistry,	
    StyleSheet,	
    Text,	
    View	
} = React;

根据 ES6 语法修改如下:

import React, {	
    AppRegistry,	
    StyleSheet,	
    Component,	
    Text,	
    View	
} from 'react-native';

可以看到,使用 ES6 语法时,我们多导入了一个名为 Component 的组件,从类的定义一节可以看出,这个 Component 是 React 组件的基类。上面代码中是从 react-native 包中导入 React 和 Component 的,但这一做法从 React Native 的 v0.25.1[2] 版本开始被标记为 deprecated,取而代之的是下面这种写法:

import React, { Component } from 'react';	
import {     	
    AppRegistry,	
    StyleSheet,	
    Text,	
    View	
} from 'react-native';

也就是说,React 和 Component 等 React 相关的组件已经从 react-native包中独立出来并放到了名为 react 的包中。这一变化其实从 2015 年 10 月份发布的 React v0.14[3] 可以看出端倪来,React 的这次版本发布一个主要的变化是将原本的 React 包拆分成 React 和 React DOM 两个包,将与浏览器渲染相关的代码独立成 React DOM,而多个平台可以共用的代码独立成 React,这样一来就为 React 在不同平台(浏览器和移动端原生系统)的通用性铺平了道路。

0?wx_fmt=png

如果你在 React Native v0.25.1 之前就已经使用 RN 进行开发,那么不可避免的会需要将 import 语法进行升级,手动修改当代码量较多时肯定是不现实的,可以使用开发者社区给出的自动转换方案 codemod-RN24-to-RN25[4]

模块的导出

在 ES6 语法中,模块的导出使用 export default 代替 module.exports,如下所示:

// ES5 语法	
var SwipeLayout = React.createClass({	
    ...	
});	
	
module.exports = SwipeLayout;	
	
// ES6 语法	
export default SwipeLayout extends React.Component {	
    ...	
}

类的定义

从 ES6 开始引入了类的概念,我们通过关键字 class 可以实现类的定义,本质上,ES6 中的 class 概念可以看作是一个语法糖,它使得开发者可以使用更面向对象的语法进行代码的编写。

ES5 中其实也是有类的概念的,只不过更多的是以模块作为称呼,ES5 中定义一个模块语法如下:

var F8App = React.createClass({	
    componentDidMount: function() {//...},	
    componentWillUnmount: function() {//...},	
    render: function() {//...},	
});

使用 ES6 语法进行改写,如下所示:

class F8App extends React.Component {	
    constructor(props) {//...}	
    componentDidMount() {//...}	
    componentWillUnmount() {//...}	
    render() {//...}	
}

可以看到,最明显的区别是 ES6 使用 React.Component 来代替 ES5 的React.createClass,同时,类中方法的定义不再需要尾随 function,而且方法之间不需要以 , 分隔;同时增加了构造函数 constructor

成员变量的声明

使用 ES5 语法时,React Native 组件的成员变量声明方式如下所示:

let SwipeLayout = React.createClass({	
    _panResponder:{},	
    _isExpanded:true,	
    _isSwiping:false,	
    ...	
});

当切换到 ES6 语法时,由于 class 引入了构造函数的概念,因此,成员变量的初始化都应该放在构造函数中,如下所示:

class SwipeLayout extends React.Component {	
    constructor(props) {	
        super(props);	
        this._panResponder = {};	
        this._isExpanded = true;	
        this._isSwiping = false;	
    }	
}

类的静态成员变量和静态成员函数的声明

ES5 语法中,在 React Native 组件中声明静态成员变量和静态成员函数的方式如下:

let F8HeaderIOS = React.createClass({	
    statics: {	
        height : 100	
        verify : function() {	
            ...	
        }	
    },	
});

ES6 语法中定义如下所示:

class F8HeaderIOS extends React.Component {	
  static height: 100;	
  static verify() {	
    ...	
  }	
}

属性的声明

在 ES5 语法中,React Native 组件中属性的声明和默认值的指定如下所示,是在组件内部声明的:

var MyComponent = React.createClass({	
    propTypes: {	
        aStringProp: React.PropTypes.string	
    },	
    getDefaultProps: function() {	
        return { aStringProp: '' };	
    },	
});

到了 ES6 的 class 中,要求属性的类型声明和默认值声明移动到组件定义的外部实现,同时在 class 类定义中将 getDefaultProps 函数重构为一个属性defaultProps,转换为 ES6 语法之后的代码如下所示:

class MyComponent extends React.Component {...}	
MyComponent.propTypes = {	
    aStringProp: React.PropTypes.string	
};	
MyComponent.defaultProps = {	
    aStringProp: ''	
};

状态的初始化

使用 ES5 语法时,React Native 组件的状态变量是在 getInitialState 函数中初始化的,如下所示:

let MyComponent = React.createClass({	
    getInitialState: function() {	
        return {	
            scrollTop: new Animated.Value(0),	
        };	
  },	
});

到了 ES6 语法中,React Native 团队修改了状态变量的初始化方式,取消了单独的 getInitialState 函数,将初始化放在构造函数中,并提供 this.state实例变量用来存储状态变量,如下所示:

class MyComponent extends React.Component {	
    constructor(props) {	
        super(props);	
        this.state = {	
            scrollTop: new Animated.Value(0),	
        };	
    }	
}

实例函数/回调函数的绑定

ES5 语法中,React Native 的 createClass 函数提供的一个便利的功能是自动绑定类作用域中的函数到组件实例,例如 createClass 里面定义的函数可以通过 this 直接指向本组件的某个成员函数,如下所示:

let MyComponent = React.createClass({	
    _handleClick : function() { // 这个方法将作为回调函数使用	
        console.log('onClick');	
    },	
	
    render : function() {	
        return (	
            <View style={styles.container}>	
                <Text style={styles.normal}	
                    onPress={this._handleClick}>	
                    确定	
                </Text>	
            </View>	
        );	
    },	
});

到了 ES6 的 class 定义中,开发者必须手动进行回调函数的绑定操作,React Native 团队推荐在组件的构造函数中进行,如下所示:

class MyComponent extends React.Component {	
    constructor(props) {	
        super(props);	
        // 手动执行绑定操作	
        this._handleClick = this._handleClick.bind(this);	
    }	
	
    _handleClick() {	
        console.log('onClick');	
    }	
	
    render() {	
        return (	
            <View style={styles.container}>	
                <Text style={styles.normal}	
                    onPress={this._handleClick}>	
                    确定	
                </Text>	
            </View>	
        );	
    }	
}

可以看到,如果 React Native 组件中存在多个回调函数需要进行 bind 操作,那么会存在较多的样板代码,如下所示:

class MyComponent extends React.Component {	
    constructor(props) {	
        super(props);	
        // 手动执行绑定操作	
        this._handleClick = this._handleClick.bind(this);	
        this._handleTouch = this._handleTouch.bind(this);	
        ...	
    }	
}

为了减少样板代码的存在,提高开发效率,我们可以将 bind 操作进行一次封装,提供一个 BaseComponent 的基类来简化绑定操作,如下所示:

class BaseComponent extends React.Component {	
    _bind(...methods) {	
        methods.forEach( (method) => this[method].bind(this) );	
    }	
}	
	
class MyComponent extends BaseComponent {	
        constructor(props) {	
        super(props);	
        // 手动执行绑定操作	
        this._bind('_handleClick', '_handleTouch');	
    }	
}

Mixins

我们知道 ES5 语法中使用 React.createClass 是支持 Mixins 的,我们可以通过给 mixins 属性赋值从而给对应的组件添加 Mixins 能力,可以添加多个 Mixins,如下所示:

var SomeMixin = {	
    doSomething() {	
	
    }	
};	
	
var F8SessionDetails = React.createClass({	
    mixins: [SomeMixin],	
	
    getInitialState: function() {	
        return {	
            scrollTop: new Animated.Value(0),	
        };	
    },	
    ...	
 });

当你切换到 ES6 中的 class 时 Mixins 功能不可用。

拓展阅读

《Refactoring React Components to ES6 Classes》[5] [6] [7] [8] [9] [10] [11]

欢迎关注我的微信公众号 ASCE1885,专注与原创或者分享 Android,iOS,ReactNative,Web 前端移动开发领域高质量文章,主要包括业界最新动态,前沿技术趋势,开源函数库与工具等。

0?wx_fmt=jpeg


[1] https://facebook.github.io/react/blog/2015/01/27/react-v0.13.0-beta-1.html [2] https://github.com/facebook/react-native/releases/tag/v0.25.1 [3] https://facebook.github.io/react/blog/2015/10/07/react-v0.14.html [4] https://github.com/sibelius/codemod-RN24-to-RN25 [5] http://www.newmediacampaigns.com/blog/refactoring-react-components-to-es6-classes [6] http://www.wangchenlong.org/2016/04/26/1604/261-rn-es6-class/ [7] http://egorsmirnov.me/2015/05/22/react-and-es6-part1.html [8] http://moduscreate.com/how-to-use-es6-arrow-functions-with-react-native/[9] http://www.ghugo.com/react-native-es6/ [10] https://toddmotto.com/react-create-class-versus-component/ [11] https://babeljs.io/blog/2015/06/07/react-on-es6-plus 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
辽B代驾管理系统对代驾订单管理、用户咨询管理、代驾订单评价管理、代驾订单投诉管理、字典管理、论坛管理、公告管理、新闻信息管理、司机管理、用户管理、管理员管理等进行集中化处理。经过前面自己查阅的网络知识,加上自己在学校课堂上学习的知识,决定开发系统选择小程序模式这种高效率的模式完成系统功能开发。这种模式让操作员基于浏览器的方式进行网站访问,采用的主流的Java语言这种面向对象的语言进行辽B代驾管理系统程序的开发,在数据库的选择上面,选择功能强大的Mysql数据库进行数据的存放操作。辽B代驾管理系统的开发让用户查看代驾订单信息变得容易,让管理员高效管理代驾订单信息。 辽B代驾管理系统具有管理员角色,用户角色,这几个操作权限。 辽B代驾管理系统针对管理员设置的功能有:添加并管理各种类型信息,管理用户账户信息,管理代驾订单信息,管理公告信息等内容。 辽B代驾管理系统针对用户设置的功能有:查看并修改个人信息,查看代驾订单信息,查看公告信息等内容。 辽B代驾管理系统针对管理员设置的功能有:添加并管理各种类型信息,管理用户账户信息,管理代驾订单信息,管理公告信息等内容。 辽B代驾管理系统针对用户设置的功能有:查看并修改个人信息,查看代驾订单信息,查看公告信息等内容。 系统登录功能是程序必不可少的功能,在登录页面必填的数据有两项,一项就是账号,另一项数据就是密码,当管理员正确填写并提交这二者数据之后,管理员就可以进入系统后台功能操作区。项目管理页面提供的功能操作有:查看代驾订单,删除代驾订单操作,新增代驾订单操作,修改代驾订单操作。公告信息管理页面提供的功能操作有:新增公告,修改公告,删除公告操作。公告类型管理页面显示所有公告类型,在此页面既可以让管理员添加新的公告信息类型,也能对已有的公告类型信息执行编辑更新,失效的公告类型信息也能让管理员快速删除。新闻管理页面,此页面提供给管理员的功能有:新增新闻,修改新闻,删除新闻。新闻类型管理页面,此页面提供给管理员的功能有:新增新闻类型,修改新闻类型,删除新闻类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值