PureComponent是优化react应用程序最重要的方法,可以减少不必要的render次数,提高性能。
原理
组件发生更新时,组件的props和state没有改变,render方法就不会触发,省去虚拟dom生成和对比的过程,其实就是react自动帮忙做了一个浅比较
if(this._compositeType === CompositeTypes.PureClass){
shouldUpdate = !shallowEqual(prevProps,nextProps)||!shallowEqual(inst.state,nextState)
}
而 shallowEqual 又做了什么呢?会比较
- Object.keys(state | props) 的长度是否一致,
- 每一个 key 是否两者都有,
- 是否是一个引用。
也就是只比较了第一层的值,确实很浅,所以深层的嵌套数据是对比不出来的。
易变数据不能使用一个引用
数据类型如果是引用类型,需要注意
import React,{PureComponent,Component} from 'react'
class App extends Component/PureComponent {
state = {
items: [1, 2, 3]
}
handleClick = () => {
const { items } = this.state;
items.pop();
this.setState({ items });
}
render() {
return (<div>
<ul>
{this.state.items.map(i => <li key={i}>{i}</li>)}
</ul>
<button onClick={this.handleClick}>delete</button>
</div>)
}
}
export default App;
如果是Component,点击delete会得到li的减少
如果是PureComponent,li不会改变,因为items用的是一个引用,所以shallowEqual结果是true。
可以改正为:
handleClick = () =>{
const {items} =this.state
items.pop()
this.setState({items:[].concat(items)})
}
每次改变都会产生一个新数组,就可以render了,但是很容易造成,数据没有改变,仍然render,浪费性能。
与 shouldComponentUpdate 共存
如果 PureComponent 里有 shouldComponentUpdate 函数的话,直接使用 shouldComponentUpdate 的结果作为是否更新的依据,没有 shouldComponentUpdate 函数的话,才会去判断是不是 PureComponent ,是的话再去做 shallowEqual 浅比较。
// 这个变量用来控制组件是否需要更新
var shouldUpdate = true;
// inst 是组件实例
if (inst.shouldComponentUpdate) {
shouldUpdate = inst.shouldComponentUpdate(nextProps, nextState, nextContext);
} else {
if (this._compositeType === CompositeType.PureClass) {
shouldUpdate = !shallowEqual(prevProps, nextProps) ||
!shallowEqual(inst.state, nextState);
}
}
有很多还不是很理解
http://www.wulv.site/2017-05-31/react-purecomponent.html
网友评论