[译]在 React.js 中使用 ES6+

news/2023/12/9 20:21:26

原文地址: http://babeljs.io/blog/2015/06/07/react-on-es6-plus/

babel.js

在今年对 Instagram Web 进行全新的设计的时候,我喜欢在写 React 组件的时候,用上一些 ES6+ 的新特性。请允许我列举这些能够改变你写 React 应用方式的新特性。比起以往,这些特性能够使你撸起码来更加容易、有趣!

类(Class)

使用 ES6+ 来编写 React 组件最明显的变化就是我们定义组件(类)的语法的方式。我们可以用定义一个继承了 React.Component 的ES6 类来代替原本使用 React.createClass 的来创建类的方式:

class Photo extends React.Component {
  render() {
    return <img alt={this.props.caption} src={this.props.src} />;
  }
}

我们可以发现这种写法使得定义组件的方式变得更加简洁:

// The ES5 way
var Photo = React.createClass({
  handleDoubleTap: function(e) { … },
  render: function() { … },
});
// The ES6+ way
class Photo extends React.Component {
  handleDoubleTap(e) { … }
  render() { … }
}

这样我们可以少写一对圆括号、一个分号、每个方法的冒号和 function 关键字。

所有生命周期方法都可以采用这种方式来定义。 但是 componentWillMount 还可以用 constructor 来代替:

// The ES5 way
var EmbedModal = React.createClass({
  componentWillMount: function() { … },
});
// The ES6+ way
class EmbedModal extends React.Component {
  constructor(props) {
    super(props);
    // Operations usually carried out in componentWillMount go here
  }
}

属性初始化(property initializers)

在 ES6+ 类中,属性类型 prop type 和默认属性 default prop 可以通过类中的 static 来声明。同时,组件的初始状态( initial state )可以通过 ES7 的属性初始化(property initializers)来完成:

// The ES5 way
var Video = React.createClass({
  getDefaultProps: function() {
    return {
      autoPlay: false,
      maxLoops: 10,
    };
  },
  getInitialState: function() {
    return {
      loopsRemaining: this.props.maxLoops,
    };
  },
  propTypes: {
    autoPlay: React.PropTypes.bool.isRequired,
    maxLoops: React.PropTypes.number.isRequired,
    posterFrameSrc: React.PropTypes.string.isRequired,
    videoSrc: React.PropTypes.string.isRequired,
  },
});
// The ES6+ way
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,
  }
  state = {
    loopsRemaining: this.props.maxLoops,
  }
}

ES7 中在构造函数( constructor )下的属性初始化操作中的 this 指向的是类的实例,所以初始状态( initial state )可以通过 this.prop (即传入的参数)来设定。

箭头函数(Arrow function)

React.createClass 方法在你的组件上做了一些额外的绑定工作,以确保在组件实实例的方法内部, this 指向的是组件实例自身。

// Autobinding, brought to you by React.createClass
var PostInfo = React.createClass({
  handleOptionsButtonClick: function(e) {
    // Here, 'this' refers to the component instance.
    this.setState({showOptionsModal: true});
  },
});

由于我们使用 ES6+ 的语法定义类的时候没有采用 React.createClass 的方式,所以,这样看来我们不得不手动来绑定这些方法中 this 的指向:

// Manually bind, wherever you need to
class PostInfo extends React.Component {
  constructor(props) {
    super(props);
    // Manually bind this method to the component instance...
    this.handleOptionsButtonClick = this.handleOptionsButtonClick.bind(this);
  }
  handleOptionsButtonClick(e) {
    // ...to ensure that 'this' refers to the component instance here.
    this.setState({showOptionsModal: true});
  }
}

幸运的是,通过 ES6+ 的箭头函数( Arrow functions )和属性初始化( property initializers )这两个特性使得把函数的 this 指向绑定为组件的实例变得非常的简单:

class PostInfo extends React.Component {
  handleOptionsButtonClick = (e) => {
    this.setState({showOptionsModal: true});
  }
}

函数体内的 this 对象,绑定定义时所在的对象,而不是使用时所在的对象。而恰好属性初始化( property initializers )刚好在这个作用域内。

动态属性名 & 字符串模板

在 ES6+ 中对 对象字面量的扩展 使得我们可以在对象字面量中使用表达式来对属性命名。如果是在 ES5 中,我们也许只能这样做:

var Form = React.createClass({
  onChange: function(inputName, e) {
    var stateToSet = {};
    stateToSet[inputName + 'Value'] = e.target.value;
    this.setState(stateToSet);
  },
});

但是,在 ES6+ 中,我们不仅可以在对象字面量属性的定义中使用表达式,还有使用使用 字符串模板

class Form extends React.Component {
  onChange(inputName, e) {
    this.setState({
      [`${inputName}Value`]: e.target.value,
    });
  }
}

析构 & 扩展运算符

我们在编写组件的过程中,经常遇到要从父组件要把自己的很多属性多传给子组件的情况。有了 ES6+ 的 析构扩展运算符 特性,这变得非常的方便:

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

我们可以把 扩展运算符 属性和普通的属性结合起来使用,这样使得我们可以利用优先级来使用属性的默认值和属性的覆盖。下面这个元素会获得一个 override 的类( class ),及时 this.props 中有传递 className 属性。

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

下面这种写法,可以给元素设定默认的 className

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

最后

我希望你能够享受 ES6+ 的这些特性给你在编写 React.js 中带来的好处。感谢我的同事他们为这篇文章作出的贡献,还有,特别的感谢 Babel 团队,使得我们可以随意的使用这些特性。

文章地址:http://blog.mcbird.cn/2015/09/11/react-on-es6-plus/


http://www.niftyadmin.cn/n/3382819.html

相关文章

SorceTree 与 Bitbucket连接

选择bitbucket&#xff0c;由于bitbucket免费的帐号最多能够8个人一起协同开发。我们项目组人数少于8个&#xff0c;私有仓库也不限制。经过半个多月的应用&#xff0c;大家感觉也还不错&#xff0c;对个人而言。在家也能訪问代码&#xff0c;对公司而言还是要server的。以下介…

小蚂蚁学cURL笔记(1)

2019独角兽企业重金招聘Python工程师标准>>> cURL的作用&#xff1a;网络上的所有资源都可以用cURL访问和下载。 如何在window下确认是否支持cURL。cmd——》输入命令 php -i 通过搜索找到curl 在linux下的检测方法。 输入命令行 php -i | grep curl (使用管道…

unity gl 画线

using UnityEngine; using System.Collections;public class TGLLine : MonoBehaviour {private static Material mat;void Start () {CreateLineMaterial();}void Update () {}//画线框用的matpublic static Material CreateLineMaterial(){mat new Material("Shader \&…

磁盘管理工具及命令总结

1、磁盘管理工具及命令总结和显示【查看磁盘或者目录的容量 df 和 du】df 查看已挂载磁盘的总容量、使用容量、剩余容量等&#xff0c;可以不加任何参数&#xff0c;默认是按k为单位显示的df常用参数有 –i -h -k –m等-i 使用inodes 显示结果-h 使用合适的单位显示&#xff…

在 Windows 下安装 WAMP(Apache、MySQL、PHP)详细图文教程

LAMP&#xff08;Linux Apache MySQL PHP&#xff09;架构是目前世界上最流行的中小型网站服务的采用的环境&#xff0c;其易用性、安全性得到了广大用户的认可。在广大 Windows 操作系统的使用者中&#xff0c;不乏想要要采用“AMP”服务器环境的 Web 开发者&#xff0c;本…

unity3d游戏物体跟着鼠标方向移动

效果&#xff1a;当点击鼠标左键时&#xff0c;游戏对象会朝鼠标点击的方向移动&#xff0c;类似魔兽争霸一样。 思路&#xff1a;把鼠标的坐标转化成世界坐标&#xff08;鼠标默认是屏幕坐标&#xff09;&#xff0c;然后当点击鼠标时&#xff0c;物体将朝着鼠标的世界坐标方向…

Swift 之 函数与闭包的应用实例

http://www.cocoachina.com/swift/20160106/14862.html 今天的博客算是比较基础的&#xff0c;还是那句话&#xff0c;基础这东西在什么时候都是最重要的。说到函数&#xff0c;只要是写过程序就肯定知道函数是怎么回事&#xff0c;今天就来讨论一下Swift中的函数的特性以及Swi…

iOS runtime 关联对象(Associated Object)

2019独角兽企业重金招聘Python工程师标准>>> &#xfeff;需求同一个类有多个alertView, 不同的alertView 点击确定按钮 执行的方法不同 alertOne 点击 确定按钮 执行 methodOne&#xff0c; alertTwo 点击确定按钮 执行 methodTwo 常规做法初始化并显示 alertOne -…

【Unity Shaders】Alpha Test和Alpha Blending

http://blog.csdn.net/candycat1992/article/details/41599167#t3写在前面 关于alpha的问题一直是个比较容易摸不清头脑的事情&#xff0c;尤其是涉及到半透明问题的时候&#xff0c;总是不知道为什么A就遮挡了B&#xff0c;而B明明在A前面。这篇文章就总结一下我现在的认识~ A…

docker资源限制

DOCKER 1.8.2 CPU的资源限制&#xff1a; -c CPU权重只有争用时权重才有意义例如&#xff0c;启动两个容器&#xff0c;使用同一个cpu权重分别为1024和512 docker run -ti --rm -c 1024 --cpuset-cpus0 centos docker run -ti --rm -c 512 --cpuset-cpus0 centos 分别执行&…

让你头晕的VR头显,背后发生了什么?

随着虚拟现实渐渐兴起&#xff0c;国内现在做虚拟现实的厂商也增多了起来。但是我经常听到有体验者向我表示&#xff1a;他戴上国外大厂诸如Oculus、Sony和Valve的VR头显的时候&#xff0c;体验十分出色&#xff0c;但是戴上国产的VR头显&#xff0c;不动的时候还好&#xff0c…

Mac Pro 下搭建maven环境

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请标明出处。 https://blog.csdn.net/lyhhj/article/details/48477191 突然想学习一下Spring MVC&#xff0c;要用到maven环境&#xff0c;自己搭建了一下&#xff0c;就记下来防止以后忘记 首先我们先下载maven http:/…

怀念你的温柔

温柔&#xff0c;多么的柔软&#xff0c;多么的诱惑。如同佳人的朦胧含羞&#xff0c;暗示着千年不化的情愫。云霞的腮红&#xff0c;是羞涩的妙韵。腼腆的温情&#xff0c;是情感的主题。始终半掩琵琶&#xff0c;让人心跳不止。 试图偷窥你的美&#xff0c;却在意识的背阴处&…

1.面向对象编程

package 面向;import org.omg.Messaging.SyncScopeHelper;public class 三角形 {//属性String nj;String bbb; int d; int j;//分别是角、边、点、角//方法 void dengbiansanjiaoxing(int d1){jd1;System.out.printf("三角形有"d1,"三角形有"d1);}}pa…

bzoj3583: 杰杰的女性朋友 4362: Graph

Description 给出一张n个点的有向图G(V,E)。对于任意两个点u,v(u可以等于v)&#xff0c;u向v的连边数为&#xff1a;∑OUT(u,i) * IN(v,i),其中1<i<K其中k和数组out,in均已知&#xff0c;现在给出m个询问&#xff0c;每次询问给出三个参数u,v,d&#xff0c;你需要回答从节…

【Python之旅】第二篇(五):基于列表、字典和元组的员工信息处理接口

1.基本需求编写一个查询员工信息表的程序&#xff0c;实现如下功能&#xff1a;&#xff08;1&#xff09;让用户输入不小于3个字符查询员工信息&#xff08;2&#xff09;通过员工号或员工个人信息可以精确或模糊查询到员工信息&#xff08;3&#xff09;输出员工信息2.实现代…
最新文章