前言

先说说 shouldComponentUpdate

提起React.PureComponent,我们还要从一个生命周期函数 shouldComponentUpdate 说起,从函数名字我们就能看出来,这个函数是用来控制组件是否应该被更新的。

React.PureComponent 通过prop和state的浅对比来实现shouldComponentUpate()。

简单来说,这个生命周期函数返回一个布尔值。

如果返回true,那么当props或state改变的时候进行更新;

如果返回false,当props或state改变的时候不更新,默认返回true。

(这里的更新不更新,其实说的是执不执行render函数,如果不执行render函数,那自然该组件和其子组件都不会重新渲染啦)

重写shouldComponentUpdate可以提升性能,它是在重新渲染过程开始前触发的。当你明确知道组件不需要更新的时候,在该生命周期内返回false就行啦!

下面是一个重写shouldComponentUpdate的例子:

class CounterButton extends React.Component {
state={
count: 1
}
shouldComponentUpdate(nextProps, nextState) {
const {color}=this.props;
const {count}=this.state;
if (color !== nextProps.color) {
return true;
}
// 重写shouldComponentUpdate若将此处count相关逻辑注释则count变化页面不渲染
// if (count !== nextState.count) {
// return true;
// }
return false;
} render() {
const {color}=this.props;
const {count}=this.state;
return (
<button
style={{color}}
onClick={() => this.setState(state => ({count: state.count + 1}))}
>
Count: {count}
</button>
);
}
}

React.Component 与 React.PureComponent

言归正传,接下来说我们今天要讨论的React.Component 与 React.PureComponent。

通常情况下,我们会使用ES6的class关键字来创建React组件:

class MyComponent extends React.Component {
// some codes here ...
}

但是,你也可以创建一个继承React.PureComponent的React组件,就像这样

class MyComponent extends React.PureComponent {
// some codes here
}

那么,问题来了,这两种方式有什么区别呢?

继承PureComponent时,不能再重写shouldComponentUpdate,否则会引发警告(报错截图就不贴了,怪麻烦的)

Warning: CounterButton has a method called shouldComponentUpdate(). shouldComponentUpdate should not be used when extending React.PureComponent. Please extend React.Component if shouldComponentUpdate is used.

继承PureComponent时,进行的是浅比较,也就是说,如果是引用类型的数据,只会比较是不是同一个地址,而不会比较具体这个地址存的数据是否完全一致

class ListOfWords extends React.PureComponent {
render() {
return <div>{this.props.words.join(',')}</div>;
}
}
class WordAdder extends React.Component { state = {
words: ['adoctors','shanks']
}; handleClick = () => {
const {words} = this.state;
words.push('tom');
this.setState({words});
console.log(words)
} render() {
const {words}=this.state;
return (
<div>
<button onClick={this.handleClick}>click</button>
<ListOfWords words={words} />
</div>
);
}
}

上面代码中,无论你怎么点击按钮,ListOfWords渲染的结果始终没变化,原因就是WordAdder的word的引用地址始终是同一个。

浅比较会忽略属性或状态突变的情况,其实也就是,数据引用指针没变而数据被改变的时候,也不新渲染组件。但其实很大程度上,我们是希望重新渲染的。所以,这就需要开发者自己保证避免数据突变。

如果想使2中的按钮被点击后可以正确渲染ListOfWords,也很简单,在WordAdder的handleClick内部,将 const words = this.state.words;

改为const words = this.state.words.slice(0);(这时的words是在原来state的基础上复制出来一个新数组,所以引用地址当然变啦)

最新文章

  1. WPF版的权限管理系统
  2. BZOJ1407 [Noi2002]Savage
  3. os.walk()
  4. NSFetchedResultsControllerDelegate不执行
  5. Java垃圾回收小结
  6. mysql笔记03 查询性能优化
  7. Unity实现相似于安卓原生项目的点击安卓返回button回到前一页的功能
  8. Java传参那些事!
  9. 【转】Android--广播BroadcastReceiver
  10. Java流的理解
  11. java表达式陷阱
  12. minihomepage.exe 百度视频迷你主页
  13. 游戏开发之UE4添加角色到场景中
  14. django框架(View)
  15. iOS应用 数据存储方式 (一)
  16. 从函数式编程到Ramda函数库(二)
  17. java第一次考试
  18. yii---往对象里面添加属性
  19. Beta冲刺 (7/7)
  20. 【数学】【CF1091D】 New Year and the Permutation Concatenation

热门文章

  1. 关于js闭包的一些浅层面的理解
  2. Apache Hive (五)DbVisualizer配置连接hive
  3. 80. Remove Duplicates from Sorted Array II (Array)
  4. Library not found for -lAPOpenSdk
  5. 少一些套路,多一些真诚 &mdash;&mdash;groovy消灭表现层套路
  6. SliceBox
  7. UID, EUID, SUID, FSUID
  8. zigbee组播通信原理
  9. https://itunes.apple.com/cn/app/apache-overkill/id410553807?mt=8uo%3D6
  10. PHP json_encode中文unicode转码问题