提起React.PureComponent
,咱们还要从一个生命周期函数 shouldComponentUpdate
提及,从函数名字咱们就能看出来,这个函数是用来控制组件是否应该被更新的。javascript
简单来讲,这个生命周期函数返回一个布尔值,若是返回true,那么当props或state改变的时候进行更新;若是返回false,当props或state改变的时候不更新,默认返回true。(这里的更新不更新,其实说的是执不执行render
函数,若是不执行render函数,那天然该组件和其子组件都不会从新渲染啦)java
重写shouldComponentUpdate
能够提高性能,它是在从新渲染过程开始前触发的。当你明确知道组件不须要更新的时候,在该生命周期内返回false
就行啦!react
下面是一个重写shouldComponentUpdate的例子:数组
class CounterButton extends React.Component { constructor(props) { super(props); this.state = {count: 1}; } shouldComponentUpdate(nextProps, nextState) { if (this.props.color !== nextProps.color) { return true; } if (this.state.count !== nextState.count) { return true; } return false; } render() { return ( <button color={this.props.color} onClick={() => this.setState(state => ({count: state.count + 1}))} > Count: {this.state.count} </button> ); } }
言归正传,接下来讲咱们今天要讨论的React.Component
与 React.PureComponent
。函数
一般状况下,咱们会使用ES6的class
关键字来建立React组件:性能
class MyComponent extends React.Component { // some codes here ... }
可是,你也能够建立一个继承React.PureComponent的React组件,就像这样this
class MyComponent extends React.PureComponent { // some codes here }
那么,问题来了,这两种方式有什么区别呢?spa
继承PureComponent时,不能再重写shouldComponentUpdate,不然会引起警告(报错截图就不贴了,怪麻烦的)指针
Warning: ListOfWords has a method called shouldComponentUpdate(). shouldComponentUpdate should not be used when extending React.PureComponent. Please extend React.Component if shouldComponentUpdate is used.code
继承PureComponent时,进行的是浅比较,也就是说,若是是引用类型的数据,只会比较是否是同一个地址,而不会比较具体这个地址存的数据是否彻底一致
class ListOfWords extends React.PureComponent { render() { return <div>{this.props.words.join(',')}</div>; } } class WordAdder extends React.Component { constructor(props) { super(props); this.state = { words: ['marklar'] }; this.handleClick = this.handleClick.bind(this); } handleClick() { // This section is bad style and causes a bug const words = this.state.words; words.push('marklar'); this.setState({words: words}); } render() { return ( <div> <button onClick={this.handleClick}>click</button> <ListOfWords words={this.state.words} /> </div> ); } }
上面代码中,不管你怎么点击按钮,ListOfWords渲染的结果始终没变化,缘由就是WordAdder的word的引用地址始终是同一个。
浅比较会忽略属性或状态突变的状况,其实也就是,数据引用指针没变而数据被改变的时候,也不新渲染组件。但其实很大程度上,咱们是但愿从新渲染的。因此,这就须要开发者本身保证避免数据突变。
若是想使2
中的按钮被点击后能够正确渲染ListOfWords,也很简单,在WordAdder的handleClick内部,将 const words = this.state.words;
改成const words = this.state.words.slice(0);
就行啦~(这时的words是在原来state的基础上复制出来一个新数组,因此引用地址固然变啦)