[译]使用 ES6+ 写 react
2016-12-16 16:59
309 查看
原文 : React on ES6+ :http://babeljs.io/blog/2015/06/07/react-on-es6-plus/ (英文不好,见谅哈)
Posted Jun 7, 2015 by Steven Luscher
This is a guest post from Steven Luscher. Steven works on Relay at Facebook – a JavaScript framework for building applications using React and GraphQL. Follow Steven on Instagram , GitHub , and Twitter .
While redesigning Instagram Web from the inside out this year, we enjoyed using a number of ES6+ features to write our React components. Allow me to highlight some of the ways that these new language features can change the way you write a React app, making it easier and more fun than ever.
虽然今年从内部重新设计Instagram Web,我们喜欢使用大量的ES6功能来编写我们的React组件。
请允许我强调一些方法,这些新的语言功能可以改变你写一个React应用程序的方式,使得它比以往任何时候更容易和更有趣。
到目前为止,我们使用ES6编写React组件的最明显的变化是使用类来定义语法,
而不是使用React.createClass方法来定义组件,我们可以定义一个扩展
Right away, you’ll notice a subtle difference – a more terse syntax is available to you when defining classes:
你会注意到一个微妙的差别 - 定义类时可以使用更简洁的语法:
Notably, we’ve dropped two parentheses and a trailing semicolon, and for each method declared we omit a colon, a function keyword, and a comma.
值得注意的是,我们删除了两个括号和一个后缀分号,对于每个声明的方法,我们省略了一个冒号,一个函数关键字和一个逗号。
All of the lifecycle methods but one can be defined as you would expect when using the new class syntax. The class’
所有的生命周期方法,可以被定义为你会期望使用新的类语法。类的构造函数现在承担了以前由componentWillMount承担的角色:
在ES6类世界中,prop 类型和默认值作为类本身的静态属性。这些,以及组件的初始状态,可以使用ES7 property 初始化:
ES7 property initializers operate inside the class’ constructor, where this refers to the the instance of the class under construction, so the initial state can still be made to depend on this.props . Notably, we no longer have to define prop defaults and the initial state object in terms of a getter function.
ES7 property 初始化器在类的构造函数中操作,其中这指的是正在构造的类的实例,因此初始状态仍然可以依赖于this.props。
值得注意的是,我们不再需要根据getter函数定义prop默认值和初始状态对象。
React.createClass方法用于对组件的实例方法执行一些额外的绑定工作,以确保在其中,this关键字将引用有问题的组件的实例。
Since we don’t involve the React.createClass method when we define components using the ES6+ class syntax, it would seem that we need to manually bind instance methods wherever we want this behavior:
因为当我们使用ES6类语法定义组件时,我们不涉及React.createClass方法,所以不管我们想要什么样的行为都需要去手动绑定实例方法:
Luckily, by combining two ES6+ features – arrow functions and property initializers – opt-in binding to the component instance becomes a breeze:
幸运的是,通过组合两个ES6特性 - 箭头函数和属性初始化器 - 选择绑定到组件实例变得轻而易举:
The body of ES6 arrow functions share the same lexical this as the code that surrounds them, which gets us the desired result because of the way that ES7 property initializers are scoped.Peek under the hood to see why this works.
ES6箭头函数的主体与它们周围的代码共享相同的词法,这得到我们所期望的结果,因为ES7属性初始化器的范围。在引擎盖下看看为什么这个工作。
对对象字面量的增强之一包括分配给派生属性名称的能力。我们可能最初做了这样的事情来设置一块状态:
Now, we have the ability to construct objects whose property names are determined by a JavaScript expression at runtime. Here, we use a template string to determine which property to set on state:
现在,我们有能力构建对象,其属性名称在运行时由JavaScript表达式确定。在这里,我们使用模板字符串来确定要设置哪个属性的状态:
通常在编写组件时,我们可能想将父组件的道具的大部分传递给子组件,但不是全部。在结合ES6解构与JSX传播属性,这成为可能没有仪式:
We can combine JSX spread attributes with regular attributes too, taking advantage of a simple precedence rule to implement overrides and defaults. This element will acquire the className “override” even if there exists a className property in this.props :
我们可以组合JSX扩展属性和常规属性,利用一个简单的优先级规则来实现覆盖和默认值。
此元素将获取className“override”,即使在this.props中存在className属性:
This element will regularly have the className “base” unless there exists a className property in this.props to override it:
此元素将定期具有className“base”,除非在this.props中存在className属性以覆盖它:
Posted Jun 7, 2015 by Steven Luscher
This is a guest post from Steven Luscher. Steven works on Relay at Facebook – a JavaScript framework for building applications using React and GraphQL. Follow Steven on Instagram , GitHub , and Twitter .
While redesigning Instagram Web from the inside out this year, we enjoyed using a number of ES6+ features to write our React components. Allow me to highlight some of the ways that these new language features can change the way you write a React app, making it easier and more fun than ever.
虽然今年从内部重新设计Instagram Web,我们喜欢使用大量的ES6功能来编写我们的React组件。
请允许我强调一些方法,这些新的语言功能可以改变你写一个React应用程序的方式,使得它比以往任何时候更容易和更有趣。
Classes
By far the most outwardly visible change to how we write React components using ES6+ comes about when we choose to use the class definition syntax . Instead of using the React.createClass method to define a component, we can define a bonafide ES6 class that extendsReact.Component:
到目前为止,我们使用ES6编写React组件的最明显的变化是使用类来定义语法,
而不是使用React.createClass方法来定义组件,我们可以定义一个扩展
React.Component的bonafide ES6类:
class Photo extends React.Component { render() { return <img alt={this.props.caption} src={this.props.src} />; } }
Right away, you’ll notice a subtle difference – a more terse syntax is available to you when defining classes:
你会注意到一个微妙的差别 - 定义类时可以使用更简洁的语法:
// The ES5 way var Photo = React.createClass({ handleDoubleTap: function(e) { … }, render: function() { … }, });
// The ES6+ way class Photo extends React.Component { handleDoubleTap(e) { … } render() { … } }
Notably, we’ve dropped two parentheses and a trailing semicolon, and for each method declared we omit a colon, a function keyword, and a comma.
值得注意的是,我们删除了两个括号和一个后缀分号,对于每个声明的方法,我们省略了一个冒号,一个函数关键字和一个逗号。
All of the lifecycle methods but one can be defined as you would expect when using the new class syntax. The class’
constructornow assumes the role previously filled by
componentWillMount:
所有的生命周期方法,可以被定义为你会期望使用新的类语法。类的构造函数现在承担了以前由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 // 这里的操作通常在componentWillMount中执行 } }
Property initializers
In the ES6+ class world, prop types and defaults live as static properties on the class itself. These, as well as the component’s initial state, can be defined using ES7 property initializers :在ES6类世界中,prop 类型和默认值作为类本身的静态属性。这些,以及组件的初始状态,可以使用ES7 property 初始化:
// 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 property initializers operate inside the class’ constructor, where this refers to the the instance of the class under construction, so the initial state can still be made to depend on this.props . Notably, we no longer have to define prop defaults and the initial state object in terms of a getter function.
ES7 property 初始化器在类的构造函数中操作,其中这指的是正在构造的类的实例,因此初始状态仍然可以依赖于this.props。
值得注意的是,我们不再需要根据getter函数定义prop默认值和初始状态对象。
Arrow functions
The React.createClass method used to perform some extra binding work on your component’s instance methods to make sure that, inside them, the this keyword would refer to the instance of the component in question.React.createClass方法用于对组件的实例方法执行一些额外的绑定工作,以确保在其中,this关键字将引用有问题的组件的实例。
// Autobinding, brought to you by React.createClass // 由React.createClass 自动绑定 var PostInfo = React.createClass({ handleOptionsButtonClick: function(e) { // Here, 'this' refers to the component instance. this.setState({showOptionsModal: true}); }, });
Since we don’t involve the React.createClass method when we define components using the ES6+ class syntax, it would seem that we need to manually bind instance methods wherever we want this behavior:
因为当我们使用ES6类语法定义组件时,我们不涉及React.createClass方法,所以不管我们想要什么样的行为都需要去手动绑定实例方法:
// 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}); } }
Luckily, by combining two ES6+ features – arrow functions and property initializers – opt-in binding to the component instance becomes a breeze:
幸运的是,通过组合两个ES6特性 - 箭头函数和属性初始化器 - 选择绑定到组件实例变得轻而易举:
class PostInfo extends React.Component { handleOptionsButtonClick = (e) => { this.setState({showOptionsModal: true}); } }
The body of ES6 arrow functions share the same lexical this as the code that surrounds them, which gets us the desired result because of the way that ES7 property initializers are scoped.Peek under the hood to see why this works.
ES6箭头函数的主体与它们周围的代码共享相同的词法,这得到我们所期望的结果,因为ES7属性初始化器的范围。在引擎盖下看看为什么这个工作。
Dynamic property names & template strings
One of the enhancements to object literals includes the ability to assign to a derived property name. We might have originally done something like this to set a piece of state:对对象字面量的增强之一包括分配给派生属性名称的能力。我们可能最初做了这样的事情来设置一块状态:
var Form = React.createClass({ onChange: function(inputName, e) { var stateToSet = {}; stateToSet[inputName + 'Value'] = e.target.value; this.setState(stateToSet); }, });
Now, we have the ability to construct objects whose property names are determined by a JavaScript expression at runtime. Here, we use a template string to determine which property to set on state:
现在,我们有能力构建对象,其属性名称在运行时由JavaScript表达式确定。在这里,我们使用模板字符串来确定要设置哪个属性的状态:
class Form extends React.Component { onChange(inputName, e) { this.setState({ [`${inputName}Value`]: e.target.value, }); } }
Destructuring & spread attributes
Often when composing components, we might want to pass down most of a parent component’s props to a child component, but not all of them. In combining ES6+ destructuring with JSX spread attributes , this becomes possible without ceremony:通常在编写组件时,我们可能想将父组件的道具的大部分传递给子组件,但不是全部。在结合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> ); } }
We can combine JSX spread attributes with regular attributes too, taking advantage of a simple precedence rule to implement overrides and defaults. This element will acquire the className “override” even if there exists a className property in this.props :
我们可以组合JSX扩展属性和常规属性,利用一个简单的优先级规则来实现覆盖和默认值。
此元素将获取className“override”,即使在this.props中存在className属性:
<div {...this.props} className="override"> … </div>
This element will regularly have the className “base” unless there exists a className property in this.props to override it:
此元素将定期具有className“base”,除非在this.props中存在className属性以覆盖它:
<div className="base" {...this.props}> … </div>
Thanks for reading
I hope that you enjoy using ES6+ language features to write React code as much as we do. Thanks to my colleagues for their contributions to this post, and thanks especially to the Babel team for making the future available to all of us, today.by web开发者 更多相关内容请访问: http://weber.pub/
本文地址: http://weber.pub/译使用-es6-写-react/335.html
相关文章推荐
- The React.js Way系列之 通过使用 Immutable.js 的 Flux 建筑结构
- React牵手JSX - 使用XML语法编写JAVASCRIPT
- 【JAVASCRIPT】React学习- 与 flux 结合使用
- Android React Native的使用细节问题
- React使用笔记1-React的JSX和Style
- Android React Native使用原生模块
- React使用指南
- React 中style的使用
- React入门 (1)—使用指南(包括ES5和ES6对比)
- React中文教程 - Advanced Components(组件高级使用)
- React使用jquery方式动态获取数据
- ReactJS material-ui 使用的css in js理念
- 这本小书的目的是引导你进入 React 和 Webpack 的世界。他们两个都是非常有用的技术,如果同时使用他们,前端开发会更加有趣。
- 关于React在meteor钟的使用
- 使用 React 的一些经验
- 【原创】使用react-active运行实例
- 【Facebook的UI开发框架React入门之八】Image的使用简介(iOS平台)-goodmao
- An iOS Developer on React Native一个资深iOS开发者对于React Native具体使用体验
- react native viewpager 使用问题
- React使用笔记2-React Components的生命周期