React.js中ES6 和 ES5寫法的一些差別
1、 Modules引入和輸出方式
ES5 使用 CommonJS 標準,一般使用 require() 用法引入模組:
var React = require('react');
var MyComponent = require('./MyComponent');
ES5輸出模組:
module.exports = MyComponent;
ES6 + import語法引入模組:
import React from 'react';
import MyComponent from './MyComponent';
ES6 輸入模組:
export default class MyComponent extends React.Component{
}
2、 Classes, 建立元件Component的方法
ES5 的React.createClass()用法
var Photo = React.createClass({
render: function(){
return (
<div>
<images alt={this.props.description} src={this.props.src} />
</div>
)
}
});
ReactDOM.render(<Photo />, document.getElementById('root' ));
es6 + class用法
class Photo extends React.Component{
render(){
return (
<div>
<images alt={this.props.description} src={this.props.src} />
</div>
)
}
};
ReactDOM.render(<Photo />, document.getElementById('root' ));
在 ES5 我們會在 componentWillMount 生命週期定義希望在 render 前執行,且只執行一次的任務
var Photo = React.createClass({
componentWillMount: function(){}
})
在 ES6+ 則是定義在 constructor 中
class Photo extends React.Component{
constructor(props){
super(props);
// 原本在 componentWillMount 操作的動作可以放在這
}
}
3、 Method 方法定義
ES5定義方法語法:
var Photo = React.createClass({
handleClick: function(e){},
render: function(){}
});
ES6可省略掉function和逗號( ’ , ’ ):
class Photo extends React.Component{
handleClick(e){}
render(){}
}
4、Property 屬性初始化
ES5 語法 使用propTypes 和 getDefaultProps來定義屬性(props)的預設值和型別:
var Todo = React.createClass({
getDefaultProps: function(){
return {
checked: false,
maxLength: 10,
};
},
propTypes: {
checked: React.PropTypes.bool.isRequired,
maxLengh: React.PropTypes.number.isRequired
},
render: function(){
return ();
}
})
ES6語法,使用 class 中的靜態屬性(static properties)來定義:
class Todo extends React.Component{
static defaultProps = {
checked: false,
maxLength: 10,
};
static propTypes = {
checked: React.PropTypes.bool.isRequired,
maxLengh: React.PropTypes.number.isRequired
};
render(){
return ();
}
}
ES6的另一種寫法:
class Todo extends React.Component{
render() {
return(
<View />
)
}
};
Todo.defaultProps = {
checked: false,
maxLength: 10,
};
Todo.propTypes = {
checked: React.PropTypes.bool.isRequired,
maxLengh: React.PropTypes.number.isRequired
};
5、 State 狀態
ES5 語法 使用 getInitialState 去初始化 state:
var Todo = React.createClass({
getInitialState: function(){
return {
maxLength: this.props.maxLength
}
}
})
在 ES6+ 中初始化 state 有兩種寫法,一種如下:
class Todo extends React.Component{
state = {
maxLength: this.props.maxLength,
}
}
另一種寫在constructor中(建議用這種,方便做一些運算):
class Todo extends React.Component{
constructor(props){
super(props);
this.state = {
maxLength: this.props.maxLength,
}
}
}
6、 Arrow functions 箭頭函式
ES5語法,在 React.createClass() 下,預設幫你繫結好 method 的 this,你無須自行繫結:
var TodoBtn = React.createClass({
handleButtonClick: function(e) {
// 此 this 指到 component 的例項(instance),而非 button
this.setState({showOptionsModal: true});
},
render: function(){
return (
<div>
<Button onClick={this.handleButtonClick}>{this.props.label}</Button>
</div>
)
},
});
ES6+ 推薦使用 bind 繫結 this 或使用 Arrow functions(它會綁定當前 scope 的 this context)兩種方式:
class TodoBtn extends React.Component{
handleButtonClick(e){
// 確認繫結 this 指到 component instance
this.setState({toggle: true});
}
render(){
// 這邊可以用 this.handleButtonClick.bind(this) 手動繫結或是 Arrow functions () => {} 用法
return (
<div>
<Button onClick={this.handleButtonClick.bind(this)} onClick={(e)=> {this.handleButtonClick(e)} }>{this.props.label}</Button>
</div>
)
},
};
無論是 bind 或是 Arrow functions,每次執行回傳都是指到一個新的函式,若需要再呼叫到這個函式,要先把它存起來:
class TodoBtn extends React.Component{
constructor(props){
super(props);
this.handleButtonClick = this.handleButtonClick.bind(this);
}
componentWillMount(){
Btn.addEventListener('click', this.handleButtonClick);
}
componentDidmount(){
Btn.removeEventListener('click', this.handleButtonClick);
}
};
7、動態屬性名和模板字串
ES5 我們要動態設定屬性名,往往需要多寫幾行程式碼才能達到目標:
var Todo = React.createClass({
onChange: function(inputName, e){
var stateToSet = {};
stateToSet[inputName + 'Value'] = e.tartet.value;
this.setState(stateToSet);
}
})
ES6+寫法相對簡單:
class Todo extends React.Component{
onChange(inputName, e) {
this.setState({
[`${inputName}Value`]: e.target.value,
})
}
}