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 单选框,多选框美化代码
Aug 01 Javascript
表单元素事件 (Form Element Events)
Jul 17 Javascript
jQuery 打造动态下滑菜单实现说明
Apr 15 Javascript
JS的replace方法详细介绍
Nov 09 Javascript
Jquery揭秘系列:ajax原生js实现详解(推荐)
Jun 08 Javascript
JS中Json数据的处理和解析JSON数据的方法详解
Jun 29 Javascript
微信小程序实现移动端滑动分页效果(ajax)
Jun 13 Javascript
解读ES6中class关键字
Nov 20 Javascript
微信小程序自定义对话框弹出和隐藏动画
Jul 19 Javascript
vue实现微信二次分享以及自定义分享的示例
Mar 20 Javascript
vue实现歌手列表字母排序下拉滚动条侧栏排序实时更新
May 14 Javascript
Vue export import 导入导出的多种方式与区别介绍
Feb 12 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
php和js如何通过json互相传递数据相关问题探讨
2013/02/26 PHP
php 5.6版本中编写一个PHP扩展的简单示例
2015/01/20 PHP
PHP开发APP端微信支付功能
2017/02/17 PHP
PHP查询分页的实现代码
2017/06/09 PHP
php mysql PDO 查询操作的实例详解
2017/09/23 PHP
laravel5.1框架model类查询的实现方法
2019/10/08 PHP
基于Jquery的温度计动画效果
2010/06/18 Javascript
讲解JavaScript中for...in语句的使用方法
2015/06/03 Javascript
Vue.js基础知识汇总
2016/04/27 Javascript
JS基于HTML5的canvas标签实现炫目的色相球动画效果实例
2016/08/24 Javascript
浅谈JSON.stringify()和JOSN.parse()方法的不同
2016/08/29 Javascript
Vue精简版风格指南(推荐)
2018/01/30 Javascript
JS实现数组的增删改查操作示例
2018/08/29 Javascript
对vue v-if v-else-if v-else 的简单使用详解
2018/09/29 Javascript
js实现抽奖的两种方法
2020/03/19 Javascript
[04:19]DOTA2亚洲邀请赛 现场花絮
2015/03/11 DOTA
pycharm 使用心得(六)进行简单的数据库管理
2014/06/06 Python
浅析Python中的join()方法的使用
2015/05/19 Python
Python利用BeautifulSoup解析Html的方法示例
2017/07/30 Python
Python计算斗牛游戏概率算法实例分析
2017/09/26 Python
Django 根据数据模型models创建数据表的实例
2018/05/27 Python
python实现ip地址的包含关系判断
2020/02/07 Python
tensorflow实现训练变量checkpoint的保存与读取
2020/02/10 Python
HTML中fieldset标签概述及使用方法
2013/02/01 HTML / CSS
HTML5 Canvas基本线条绘制的实例教程
2016/03/17 HTML / CSS
Html5 new XMLHttpRequest()监听附件上传进度
2021/01/14 HTML / CSS
Hurley官方网站:扎根于海滩生活方式的全球青年文化品牌
2020/05/18 全球购物
为什么需要版本控制
2016/10/28 面试题
应届生财务会计求职信
2013/11/05 职场文书
大学生收银员求职信分享
2014/01/02 职场文书
开朗女孩的自我评价
2014/02/10 职场文书
邀请书格式范文
2015/02/02 职场文书
和谐拯救危机观后感
2015/06/15 职场文书
2016三八妇女节慰问信
2015/11/30 职场文书
教你如何用python开发一款数字推盘小游戏
2021/04/14 Python
python神经网络 tf.name_scope 和 tf.variable_scope 的区别
2022/05/04 Python