React.js中常用的ES6写法总结(推荐)


Posted in Javascript onMay 09, 2017

一 模块

1 引入模块以便使用

用import实现:

import '模块文件地址'
import 组件 from '模块文件地址'

2 导出模块

用export default实现:

export default class MyComponent extends Component{
  ...
}

引用:

import MyComponent from './MyComponent';

二 组件

1 定义组件

通过定义一个继承自React.Component的class来定义一个组件类:

class Photo extends React.Component {
  render() {
    ...
  }
}

2 定义组件方法

直接用名字(){},很像Java定义类方法的写法:

class Photo extends React.Component {
  componentWillMount() {

  }
  render() {
    return (
      <Image source={this.props.source} />
    );
  }
}

3 定义组件的属性类型和默认属性

统一使用static成员来实现:

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,
  }; // 注意这里有分号
  render() {
    return (
      <View />
    );
  } // 注意这里既没有分号也没有逗号
}

注意: 对React而言,static成员在IE10及之前版本不能被继承,而在IE11和其它浏览器上可以,有时会带来一些问题。React Native则不用担心这个问题。

4 初始化STATE

在构造函数中初始化(这样可以根据需要做一些计算):

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

5 把方法作为回调提供并使用

ES5下可以这么做:

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

在ES5下,React.createClass会把所有的方法都bind一遍,这样可以提交到任意的地方作为回调函数,而this不会变化。但官方现在认为这是不标准、不易理解的。

ES6下,需要通过bind来绑定this引用,或者使用箭头函数(它会绑定当前scope的this引用)来调用:

//ES6
class PostInfo extends React.Component
{
  handleOptionsButtonClick(e){
    this.setState({showOptionsModal: true});
  }
  render(){
    return (
      <TouchableHighlight 
        onPress={this.handleOptionsButtonClick.bind(this)}
        onPress={e=>this.handleOptionsButtonClick(e)}
        >
        <Text>{this.props.label}</Text>
      </TouchableHighlight>
    )
  },
}

箭头函数是在这里定义了一个临时的函数,箭头函数的箭头=>之前是一个空括号、单个的参数名、或用括号括起的多个参数名,而箭头之后可以是一个表达式(作为函数的返回值),或者是用花括号括起的函数体(需要自行通过return来返回值,否则返回的是undefined)。

即:箭头函数箭头前是参数,箭头后是函数体或返回值。

注意:

不论是bind还是箭头函数,每次被执行都返回的是一个新的函数引用,因此如果你还需要函数的引用去做一些别的事情(譬如卸载监听器),那么必须自己保存这个引用:

// 错误的做法
class PauseMenu extends React.Component{
  componentWillMount(){
    AppStateIOS.addEventListener('change', this.onAppPaused.bind(this));
  }
  componentDidUnmount(){
    AppStateIOS.removeEventListener('change', this.onAppPaused.bind(this));
  }
  onAppPaused(event){
  }
}
// 正确的做法
class PauseMenu extends React.Component{
  constructor(props){
    super(props);
    this._onAppPaused = this.onAppPaused.bind(this);//注意这里
  }
  componentWillMount(){
    AppStateIOS.addEventListener('change', this._onAppPaused); //还有这里
  }
  componentDidUnmount(){
    AppStateIOS.removeEventListener('change', this._onAppPaused);
  }
  onAppPaused(event){
  }
}

三 Mixins

ES5下,经常使用mixin来为类添加一些新的方法,如PureRenderMixin:

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

 render: function() {
  return <div className={this.props.className}>foo</div>;
 }
});

但React官方已经不再打算在ES6里继续推行Mixin,官方推荐,对于库编写者而言,应尽快放弃Mixin的编写方式,推荐一种新的编码方式:

//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 <ComposedComponent {...this.props} data={this.state.data} />;
  }
};
//HigherOrderComponent.js
import { Enhance } from "./Enhance";

class MyComponent {
  render() {
    if (!this.data) return <div>Waiting...</div>;
    return <div>{this.data}</div>;
  }
}

export default Enhance(MyComponent); // Enhanced component

用一个“增强函数”,来为某个类增加一些方法,并且返回一个新类,这无疑能实现mixin所实现的大部分需求。

四 解构与属性延展

结合使用ES6+的解构和属性延展,在给子组件传递一批属性更为方便了。下面的例子把className以外的所有属性传递给div标签:

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>
    );
  }
}

下面这种写法,则是传递所有属性的同时,用新的className值进行覆盖({…this.props}写在前边):

<div {...this.props} className="override">
  …
</div>

这个例子则相反,如果属性中没有包含className,则提供默认的值,而如果属性中已经包含了,则使用属性中的值({…this.props}写在后边)

<div className="base" {...this.props}>
  …
</div>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript Event学习第十章 一些可替换的事件对
Feb 10 Javascript
javascript cookie操作类的实现代码小结附使用方法
Jun 02 Javascript
js的表单操作 简单计算器
Dec 29 Javascript
Jquery实现搜索框提示功能示例代码
Aug 13 Javascript
textarea 控制输入字符字节数(示例代码)
Dec 27 Javascript
Angularjs编写KindEditor,UEidtor,jQuery指令
Jan 28 Javascript
Express实现前端后端通信上传图片之存储数据库(mysql)傻瓜式教程(二)
Dec 10 Javascript
浅谈pc端rem字体设置的问题
Aug 03 Javascript
layer弹出的iframe层在执行完毕后关闭当前弹出层的方法
Aug 17 Javascript
vue 监听键盘回车事件详解 @keyup.enter || @keyup.enter.native
Aug 25 Javascript
angular 服务的单例模式(依赖注入模式下)详解
Oct 22 Javascript
JS实现盒子跟着鼠标移动及键盘方向键控制盒子移动效果示例
Jan 29 Javascript
js上传图片预览的实现方法
May 09 #Javascript
react开发中如何使用require.ensure加载es6风格的组件
May 09 #Javascript
Vue2单一事件管理组件通信
May 09 #Javascript
react-router实现按需加载
May 09 #Javascript
BootStrap表单时间选择器详解
May 09 #Javascript
兼容浏览器的js事件绑定函数(详解)
May 09 #Javascript
JS触摸与手势事件详解
May 09 #Javascript
You might like
为PHP5.4开启Zend OPCode缓存
2014/12/26 PHP
php数组函数array_key_exists()小结
2015/12/10 PHP
PHP数学运算函数大汇总(经典值得收藏)
2016/04/01 PHP
PHP pthreads v3下同步处理synchronized用法示例
2020/02/21 PHP
用js计算页面执行时间的函数
2006/12/07 Javascript
JS的IE和Firefox兼容性集锦
2006/12/11 Javascript
一个不错的用JavaScript实现的UBB编码函数
2007/03/09 Javascript
jquery分页对象使用示例
2014/04/01 Javascript
javascript实现网页字符定位的方法
2015/07/14 Javascript
jQuery实现的产品自动360度旋转展示特效源码分享
2015/08/21 Javascript
jquery版轮播图效果和extend扩展
2017/07/18 jQuery
vue2.0 兄弟组件(平级)通讯的实现代码
2018/01/15 Javascript
Vue常见面试题整理【值得收藏】
2018/09/20 Javascript
浅谈对于“不用setInterval,用setTimeout”的理解
2019/08/28 Javascript
对layui中table组件工具栏的使用详解
2019/09/19 Javascript
python对指定目录下文件进行批量重命名的方法
2015/04/18 Python
通过pykafka接收Kafka消息队列的方法
2018/12/27 Python
Python实现计算对象的内存大小示例
2019/07/10 Python
python requests使用socks5的例子
2019/07/25 Python
简单介绍python封装的基本知识
2019/08/10 Python
Python使用百度api做人脸对比的方法
2019/08/28 Python
Python 2种方法求某个范围内的所有素数(质数)
2020/01/31 Python
Tensorflow:转置函数 transpose的使用详解
2020/02/11 Python
css3 position fixed固定居中问题解决方案
2014/08/19 HTML / CSS
英国最全面的橄榄球联盟门票网站:Live Rugby Tickets
2018/10/06 全球购物
Linux机考试题
2015/07/17 面试题
医学生实习自荐信
2013/10/01 职场文书
报社实习生自荐信
2014/01/24 职场文书
趣味比赛活动方案
2014/02/15 职场文书
领导班子民主生活会整改措施(工商局)
2014/09/21 职场文书
质监局领导班子践行群众路线整改方案
2014/10/26 职场文书
社保缴纳证明申请书
2014/11/03 职场文书
给医院的感谢信
2015/01/21 职场文书
对领导班子的意见和建议
2015/06/08 职场文书
小学语文课《掌声》教学反思
2016/03/03 职场文书
了解MySQL查询语句执行过程(5大组件)
2022/08/14 MySQL