1、无状态(stateless
)组件的简写
1 2 3 4 |
const clickHandler = e=>alert(e.type); const Button = props=>(<button type="button" onClick={clickHandler} className={props.className}>Button</button>); |
1 2 3 4 5 6 |
const Button = props=> { const clickHandler = e=>alert(e.type); return (<button type="button" onClick={clickHandler} className={props.className}>Button</button>); }; |
1 2 3 4 5 6 |
const Button = props=> { const clickHandler = e=>alert(e.type); return (<button type="button" onClick={this.clickHandler} className={props.className}>Button</button>); }; |
2、将上一级props
赋值给state
1 2 3 4 5 6 7 8 9 |
class Button extends React.Component { constructor(props) { super(); this.state = props; } render() { return (/*...*/); } } |
1 2 3 4 5 6 |
class Button extends React.Component { state = this.props; render() { return (/*...*/); } } |
1 2 3 4 5 6 7 8 9 |
class Button extends React.Component { constructor() { super(); this.state = this.props;//undefined } render() { return (/*...*/); } } |
3、声明变量多数使用const
,少数使用let
,不使用var
const
与let
是块级作用域,而var
是函数作用域。虽然const
是不可变量,但是用const
声明的对象与数组却可以被操作属性,除非要整体替换。
1 2 3 4 5 6 7 |
const name = { firstName: 'lai' }; const list = []; let age = "child"; name.lastName = 'chuanfeng';//{ firstName: 'lai', lastName: 'chuanfeng' } list.push('person');//['person'] name = "laichuanfeng";//TypeError: Assignment to constant variable. age = "younger";//younger |
4、快速存取对象的属性
1 2 3 4 5 6 7 8 9 10 |
const student = { name: 'Mike', gender: 'male' }; const engineer = { name: 'John', gender: 'male' }; // const person = { student: student, engineer: engineer }; const person = { student, engineer }; |
1 2 3 4 5 6 7 8 9 10 11 |
const person = { student: { name: 'Mike', gender: 'male' }, engineer: { name: 'John', gender: 'male' } }; const { student, engineer }=person; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class Container extends React.Component{ constructor(){ super(); this.state={ className:'button' }; this.updateClassName=this.updateClassName.bind(this); } updateClassName(className){ return this.setState({className});//this.setState({className:className}) } render(){ return (<Button update={this.updateClassName} />); } } |
5、state
更新助手react-addons-update
假设有一个结构略复杂的state
,假如我想更新firstPerson
的name
属性,该如何操作?下面举例错误的用法,正确的用法,以及 state 更新助手。
1 2 3 4 5 6 7 8 9 10 |
this.state = { firstPerson: { name: 'Mike', gender: 'male' }, secondPerson: { name: 'Lily', gender: 'female' } }; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
this.setState({ firstPerson: { name: 'John' } }); // gender 属性被清除 // { // firstPerson: { // name: 'John', // }, // secondPerson: { // name: 'Lily', // gender: 'female' // } // } |
1 2 3 4 5 6 |
this.setState({ firstPerson: { name: 'John', gender: this.state.firstPerson.gender } }); |
1 2 3 4 |
this.state.firstPerson.name = 'John'; this.setState({ firstPerson: this.state.firstPerson }); |
但如果state
的结构比较复杂,以上两种写法就可能会变成:
1 2 3 4 5 6 7 8 9 |
this.setState({ firstPerson: { a: 'John', b: this.state.firstPerson.b, c: this.state.firstPerson.c, d: this.state.firstPerson.d /*...*/ } }); |
1 2 3 4 5 6 |
this.state.firstPerson.a.b.c.d.e.f = 'John'; this.state.firstPerson.a.b.c.d.x.y = 'male'; /*...*/ this.setState({ firstPerson: this.state.firstPerson }); |
但是借助react-addon-update
,我们可以更直观的书写:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
import update from 'react-addons-update';//npm引入方式,需安装 react-addons-update const update = React.addons.update;//<script>引入方式,需使用 react-width-addons.js const firstPerson = update(this.state.firstPerson, { a: { b: { c: { d: { e: { f: { $set: 'John' } }, x: { y: { $set: 'male' } } } } } } }); this.setState({ firstPerson }); |
这种方式来源于 MongoDB 的操作器,有效的命令如下:
{$push: array}
在目标上所有array
里的项目。{$unshift: array}
在目标上unshift()
所有array
里的项目。{$splice: array of arrays}
在目标上对于每一个arrays
里的项目使用项目提供的参数调用splice()
。{$set: any}
整个替换目标.{$merge: object}
合并 目标和object
的 keys.{$apply: function}
传递当前的值给 function 并用返回值更新它。
6、state
初始化
1 2 3 4 5 6 7 8 9 10 |
export default class Container extends React.Component { constructor() { super(); this.state = { autoPlay: false, maxLoops: 10 }; } /*...*/ } |
1 2 3 4 5 6 7 |
export default class Container extends React.Component { state = { autoPlay: false, maxLoops: 10 }; /*...*/ } |
7、默认props
1 2 3 4 5 6 7 |
export default class Container extends React.Component { static defaultProps = { autoPlay: false, maxLoops: 10 }; /*...*/ } |
1 2 3 4 5 6 7 |
export default class Container extends React.Component { /*...*/ } Container.props = { autoPlay: false, maxLoops: 10 }; |
8、验证props
1 2 3 4 5 6 7 8 |
import React, { Component, PropTypes } from 'react'; export default class Container extends Component { static propTypes = { autoPlay: PropTypes.bool.isRequired, maxLoops: PropTypes.number.isRequired }; /*...*/ } |
1 2 3 4 5 6 7 8 |
import React, { Component, PropTypes } from 'react'; export default class Container extends Component { /*...*/ } Container.propTypes = { autoPlay: PropTypes.bool.isRequired, maxLoops: PropTypes.number.isRequired }; |