PureComponent
- 看一下下面的例子对比
- 这种写法不会造成视图的更新,但是render方法却执行了这就浪费性能了
- 为什么会出现这种问题尼?
- 继承Component,当修改的值的地址没有改变时候,react会被判定值没有改变,所以视图不进行更新
import React, { Component } from 'react'
export default class PureComp extends Component {
state = {
arr: [10, 20]
}
handler = () => {
let { arr } = this.state;
arr.push(30);
this.setState({
arr
})
}
render() {
let { arr } = this.state;
console.log(arr, 'render');
return (
<div>
{ arr }
<br />
<button onClick={ this.handler }>处理</button>
</div>
)
}
}

- 继承PureComponent
- 继承React.PureComponent,会默认创建一个 shouldComponentUpdate
- 在这个生命周期中做了一个浅比较
- 拿最新修改的值和状态,和之前的属性状态进行比较,如果一样则不去更新
import React, { PureComponent } from 'react'
export default class PureComp extends PureComponent {
state = {
arr: [10, 20]
}
handler = () => {
let { arr } = this.state;
arr.push(30);
this.setState({
arr
})
}
render() {
let { arr } = this.state;
console.log(arr, 'render');
return (
<div>
{ arr }
<br />
<button onClick={ this.handler }>处理</button>
</div>
)
}
}

继承 Component这个类去简单模拟 PureComponent这个类
import React, { Component, PureComponent } from 'react'
function isObject(obj) {
if(typeof obj === 'object' && obj !== null) return true;
}
function compare(obj1, obj2) {
if(obj1 === obj2) return true;
if(!isObject(obj1) && !isObject(obj2)) return false;
let keys1 = Reflect.ownKeys(obj1),
keys2 = Reflect.ownKeys(obj2);
if(keys1.length !== keys2.length) return false;
return keys1.every(key => {
return obj1[key] === obj2[key];
})
}
export default class PureComp extends Component {
state = {
arr: [10, 20]
}
handler = () => {
let { arr } = this.state;
arr.push(30);
this.setState({
arr
})
}
shouldComponentUpdate(nextProps, nextState) {
return !compare(this.props, nextProps) || !compare(this.state, nextState);
}
render() {
let { arr } = this.state;
console.log(arr, 'render');
return (
<div>
{ arr }
<br />
<button onClick={ this.handler }>处理</button>
</div>
)
}
}

总结
- PureComponent可以做性能的优化
- this.setState设置值的时候,不要再原来的地址上操作 or this.forceUpdate()跳过shouldComponentUpdate(不推荐使用)
- 项目中直接使用 PureComponent就行了,如非必要不要去搞事情