# ES5&ES6 写法对照表(react) #### 来源: [React on ES6+](https://babeljs.io/blog/2015/06/07/react-on-es6-plus)
[React/React Native 的 ES5 ES6 写法对照表](http://bbs.reactnative.cn/topic/15/react-react-native-%E7%9A%84es5-es6%E5%86%99%E6%B3%95%E5%AF%B9%E7%85%A7%E8%A1%A8) ## class 定义语法 > 值得注意的是,我们已经删除了两个括号和一个后缀分号,而对于每个声明的方法,我们都省略了一个冒号,一个 function 关键字和一个逗号。 ```javascript class Photo extends React.Component { render() { return {this.props.caption} } } // The ES5 way var Photo = React.createClass({ handleDoubleTap: function(e) { ... } render: function() { ... } }) //ThE ES6 way class Photo extends React.Component { handleDoubleTap(e) { ... } render() { ... } } ``` ## 生命周期方法 > 所有的生命周期方法,但可以定义为使用新的类语法期望的。该课程 constructor 现在承担以前填写的角色 componentWillMount: ```javascript // es5 var EmbedModal = React.createClass({ componentWillMount: function() { ... } }) // es6 class EmbedModal extends React.createClass ( construtor(props) { super(props); // Operations usually carried out in componentWillMount go here } ) ``` ## 属性初始化 > ES7 属性初始化器在类的构造函数中运行,其中 this 指的是正在构建的类的实例,所以初始状态仍然可以依赖于 this.props。值得注意的是,我们不再需要根据吸气功能定义道具默认值和初始状态对象。 ```javascript // es5 var Video = React.createClass({ getDefaultProps: function() { return { autoPlay: flase, maxLoops: 10, }; }, getInitalState: function() { return { loopsRemaining: this.props.maxloops, }; }, propsTypes: { autoPlay: React.PropsTypes.bool.isRequired, maxloops: React.PropsTypes.number.isRequired, posterFrameSrc: React.PropsTypes.string.isRequired, videoSrc: React.PropsTypes.string.isRequired, }, }); // es6 class Video extends React.Component { static defaultProps = { autoPlay: false, maxloops: 10, }; static propsTypes = { autoPlay: React.PropsTypes.bool.isRequired, maxloops: React.propsTypes.number.isRequired, posterFrameSrc: React.PropsTypes.string.isRequired, videoSrc: React.PropsTypes.string.isRequired, }; state = { loopsRemaining: this.props.maxloops, }; } ``` ## 箭头函数说明 > 该 React.createClass 方法用于对组件的实例方法执行一些额外的绑定工作,以确保其中的 this 关键字将引用该组件的实例。 ```javascript // 自动绑定React.createClass var PostInfo = React.createClass({ handleOptionsButtonClick: function(e) { // 这里,'this' 是指组件实例。 this.setState({ showOptionModal: true }); }, }); ``` > 由于我们 React.createClass 在使用 ES6 +类语法定义组件时不涉及该方法,所以我们需要手动绑定实例方法,无论我们想要这种行为: ```javascript // 手动绑定,无论你是否需要 class PostInfo extends React.Component { construtor(props) { super(props); // 手动将此方法绑定到组件实例中… this.handleOptionsButtonClick = this.handleOptionsButtonClick.bind(this); } handleOptionsButtonClick(e) { // …为了确保'this'指的是组件实例。 this.setState({ showOptionsModal: true }); } } ``` > 幸运的是,通过组合两个 ES6 +功能 - 箭头函数和属性初始值设置 - 选择加入到组件实例的绑定变得轻而易举: ```javascript class PostInfo extends React.Component { handleOptionsButtonClick = (e) => { this.setState({ showOptionsModal: true }); }; } ``` > ES6 箭头函数的主体具有与它们周围 this 的代码相同的词汇,这使得我们获得了期望的结果,因为 ES7 属性初始化器的作用域的方式。在罩下看,看看为什么这个工作。 ## 动态属性名称和模板字符串 > 其中的增强对象文本包括分配给派生属性名称的能力。我们原本可以做这样的事情来设定一个状态: ```javascript var From = React.createClass({ onChange: function(inputName, e) { var stateToSet = {}; stateToSet[inputName + 'Value'] = e.targe.value; this.setState(stateToset); }, }); // 现在,我们有能力构建在运行时由JavaScript表达式决定其属性名称的对象。在这里,我们使用模板字符串来确定要设置的属性: class From extends React.Component { onChange(inpuntName, e) { this.setState({ [`$(inputName)value`]: e.targe.value, }); } } ``` ## 解构和传播属性 > 通常在组成组件时,我们可能希望将大部分父组件的道具传递给子组件,但并不是全部。将 ES6 + 解构与 JSX 传播属性相结合,无需仪式即可实现: ```javascript class AutoloadingPostsGrid extends React.Component { render() { const { className, ...others // 包含所有特性this.props除了类名 } = this.props; return (
); } } // 我们可以将JSX传播属性与常规属性结合起来,利用简单的优先级规则来实现覆盖和默认值。该元素将获得className“覆盖”,即使存在一个className财产this.props:
...
// This element will regularly have the “base” unless there exists a property in to override it:
...
``` ## 模块 ```javascript // 引用 // es5 var React = require("react"); var { Component, PropsTypes } = React; //引用react抽象组件 var ReactNative = require("react-native"); var { Image, Text, } = ReactNative; // 引用具体的React Native组件 // es6 import写法更为标准 import React, { Component, PropsTypes, } from 'react'; import { imange, Text, } from 'react-native' ``` ## 导出单个类 > 在 ES5 里,要导出一个类给别的模块用,一般通过 module.exports 来导出 ```javascript // es5 var MyComponent = React.createClass({ // 函数 }); // es6 export default class MyComponent extends Component { // 函数 } // 引用 class // es5 var MyComponent = require('./MyComponent'); // es6 import MyComponent from './MyComponent'; ``` ## 定义组件 > es5 在 ES5 里,通常通过 React.createClass 来定义一个组件类,像这样: ```javascript var Photo = React.createClass({ render: function() { return ; }, }); ``` > 在 ES6 里,我们通过定义一个继承自 React.Component 的 class 来定义一个组件类,像这样: ```javascript class Photo extends React.Component { render() { return ; } } ``` ## 给组件定义方法 > 给组件定义方法不再用 名字: function()的写法,而是直接用名字(),在方法的最后也不能有逗号了。 ```javascript // es5 var Photo = React.createClass({ componentWillMount: function() { // 函数 }, render: function() { return ( ); }, }); // es6 class Photo extends React.Component { componentWillMount() { // 函数 }, render() { return ( ); } } ``` ## 定义组件的属性类型和默认属性 > 在 ES5 里,属性类型和默认属性分别通过 propTypes 成员和 getDefaultProps 方法来实现 ```javascript // es5 var video = React.createClass({ getDefaultProps: function() { return { autoPlay: false, maxloops: 10, }; }, PropsTypes: { autoPlay: React.PropsTypes.bool.isRequired, maxloops: React.PropsTypes.number.isRequired, posterFrameSrc: React.PropsTypes.string.isRequired, videoSrc: React.PropsTypes.string.isRequired, }, render: function() { return: function() { }; } }) ``` > 在 ES6 里,可以统一使用 static 成员来实现 ```javascript //es6 class Video extends React.Component { static defaultProps = { autoPlay: flase, maxloops: 10, }; // 注意这里有分号 static propsTypes = { autoPlay: React.PropsTypes.bool.isRequired, maxloops: React.PropsTypes.number.isRequired, posterFrameSrc: React.PropsTypes.string.isRequired, videoSrc: React.PropsTypes.string.isRequired, }; // 注意这里有分号 render() { return ; } } ``` > 也有人这么写,虽然不推荐,但读到代码的时候你应当能明白它的意思: ```javascript //es6 class Videlo extends React.Component { render() { return