您的位置:首页 > Web前端 > React

[译]使用 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应用程序的方式,使得它比以往任何时候更容易和更有趣。

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 extends
React.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’
constructor
now 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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  react es6 ecmascrit ES2015