结合 ES6+ 开发 React 组件
2015-07-09 17:09
621 查看
这是 Steven Luscher 写的一篇关于 React 的文章,Steven Luscher 擅长使用 React 和 GraphQL 构建应用。
原文地址:http://babeljs.io/blog/2015/06/07/react-on-es6-plus/
当重新设计 Instagram Web 的时候,使用了一些 ES6+ 的特性来编写 React 组件。在这里简要的说一下这些语言新特性对 React 应用的开发有什么影响,这些 ES6+ 特性使得 React 开发更简单更有趣。
现在,你就会发现一个微妙的差异 —— 当使用定义类的时候语法更简洁:
值得关注的是,我们去掉了两个括号和一个分号,每个方法声明我们省略了一个冒号,一个关键字和一个分号。
当使用新的类定义时,所有的生命周期方法至少有一个是符合你期望的。类的 constructor 现在假设 role 之前是通过 componentWillMount 填充的:
ES7 属性初始化程序操作内部类的 constructor,
自从我们不参与
幸运的是,通过绑定两个 ES6+ 特性 – arrow functions 和属性初始化程序 – 可以选择绑定组件实例:
ES6 的 arrow 函数体分享相同的词
现在,我们有能力构造通过一个运行时 JavaScript 表达式确定属性名称的对象。这里,我们使用了一个模板字符串来确定哪个属性设置状态:
我们可以结合 JSX 传播属性和常规属性,利用一个简单的优先原则实现 overrides 和 defaults。这个元素会要求
这个元素常规来说需要
希望大家能享受 ES6+ 语言特性给 React 开发带来的一些便利。
原文地址:http://babeljs.io/blog/2015/06/07/react-on-es6-plus/
当重新设计 Instagram Web 的时候,使用了一些 ES6+ 的特性来编写 React 组件。在这里简要的说一下这些语言新特性对 React 应用的开发有什么影响,这些 ES6+ 特性使得 React 开发更简单更有趣。
类
迄今为止,最能体现我们使用 ES6+ 来编写 React 组件的就是我们选择使用类定义语法。替代了使用React.createClass方法来定义一个组件,我们可以定义一个 bonafide ES6 类来扩展
React.Component:
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() { … } }
值得关注的是,我们去掉了两个括号和一个分号,每个方法声明我们省略了一个冒号,一个关键字和一个分号。
当使用新的类定义时,所有的生命周期方法至少有一个是符合你期望的。类的 constructor 现在假设 role 之前是通过 componentWillMount 填充的:
// 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 } }
属性初始化程序
在 ES6+ 类的世界里,prop types 和 defaults live 在类自身作为静态属性。这些,在组件的初始化状态也是一样的,可以使用 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指向 construction 的类实例,所以初始化状态可以依赖于
this.props。值得关注的是,我们不再定义 prop 默认值和使用 getter 函数初始化状态对象。
Arrow 函数
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}); }, });
自从我们不参与
React.createClass方法,而是使用 ES6+ 类语法定义组件,看似需要手动绑定实例方法:
// 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 和属性初始化程序 – 可以选择绑定组件实例:
class PostInfo extends React.Component { handleOptionsButtonClick = (e) => { this.setState({showOptionsModal: true}); } }
ES6 的 arrow 函数体分享相同的词
this,用这来围绕他们的代码,这些可以达到我们预期的结果,也是 ES7 属性初始化程序在域内的方式。 Peek under the hood 来看看为什么能实现。
动态属性名称 & 模板字符串
其中一个对象常量增强是可以分配到一个派生属性名称。我们最初可能会像下面这样设置一些状态:var Form = React.createClass({ onChange: function(inputName, e) { var stateToSet = {}; stateToSet[inputName + 'Value'] = e.target.value; this.setState(stateToSet); }, });
现在,我们有能力构造通过一个运行时 JavaScript 表达式确定属性名称的对象。这里,我们使用了一个模板字符串来确定哪个属性设置状态:
class Form extends React.Component { onChange(inputName, e) { this.setState({ [`${inputName}Value`]: e.target.value, }); } }
解构 & 传播属性
通常在编写组件的时候,我们可能想把大部分父组件的 props 传递给子组件,但不是所有。结合 ES6+ 解构和 JSX 传播属性,这个不需要多余的部分就能实现: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> ); } }
我们可以结合 JSX 传播属性和常规属性,利用一个简单的优先原则实现 overrides 和 defaults。这个元素会要求
className“override” 甚至是在 this.props 存在
className属性:
<div {...this.props} className="override"> … </div>
这个元素常规来说需要
className“base” ,除非 this.props 有
className属性覆盖:
<div className="base" {...this.props}> … </div>
希望大家能享受 ES6+ 语言特性给 React 开发带来的一些便利。
相关文章推荐
- 关于React在meteor钟的使用
- 高性能I/O设计模式Reactor和Proactor
- The Reactor pattern 目的和优点
- ReactiveCocoa - iOS开发的新框架
- React Native专栏 说在前面
- Netty源码解读(四)Netty与Reactor模式
- reactor和proactor模式
- reactjs 视频教程
- ReactJS学习笔记八:动画
- 用react native 做的一个推酷客户端
- 用 `react native` 模仿做的一个美团客户端首页
- 天猫Web架构/Pad客户端负责人:如何评价 React Native?
- reactor官方文档译文(2)Reactor-core模块
- ReactJS学习笔记七:表单
- React 初探
- 由ReactJS的Hello world说开来
- 深入理解JavaScript的React框架的原理
- 超级给力的JavaScript的React框架入门教程
- reactor模式和proactor模式
- [iOS]ReactiveCocoa安装方法