PureComponent
出现,不得不说起React
的更新机制,当state
或者props
变化,React
会从根组件从上往下更新渲染,当然有些组件的state
或props
变化没有发生变化,也会更新渲染,这样就带来了性能上的问题,因为React
在类组件带来了生命周期shouldComponentUpdate
函数来组件渲染。
shouldComponentUpdate(nextProps, nextState)
shouldComponentUpdate
函数返回true
进行更新,返回false
组件不进行更新。
PureComponent
内部帮组我们实现了,shouldComponentUpdate
, props和state的浅对比来实现,代码如下:
if (this._compositeType === CompositeTypes.PureClass) {
shouldUpdate = !shallowEqual(prevProps, nextProps)
|| !shallowEqual(inst.state, nextState);
}
通过判断当前的props
和nextProps
或者state
和nextState
来比较是否更新。
前比较shallowEqual
实现如下:
function shallowEqual(objA: mixed, objB: mixed): boolean {
if (is(objA, objB)) {
return true;
}
if (typeof objA !== 'object' || objA === null ||
typeof objB !== 'object' || objB === null) {
return false;
}
const keysA = Object.keys(objA);
const keysB = Object.keys(objB);
if (keysA.length !== keysB.length) {
return false;
}
// Test for A's keys different from B.
for (let i = 0; i < keysA.length; i++) {
if (
!hasOwnProperty.call(objB, keysA[i]) ||
!is(objA[keysA[i]], objB[keysA[i]])
) {
return false;
}
}
return true;
}
function is(x: mixed, y: mixed): boolean {
// SameValue algorithm
if (x === y) { // Steps 1-5, 7-10
// Steps 6.b-6.e: +0 != -0
// Added the nonzero y check to make Flow happy, but it is redundant
return x !== 0 || y !== 0 || 1 / x === 1 / y;
} else {
// Step 6.a: NaN == NaN
return x !== x && y !== y;
}
}
判断过程如下:
- 通过
is
函数判断两个值是否相等,is
实际上是Object.is
的垫片。 - 判断两个对象属性
keysA.length !== keysB.length
长度是否相等。 - 如果两个对象的属性长度相等,在进行判断属性的名字是否一样。
可能会因深层的数据不一致而产生错误的否定判断,从而shouldComponentUpdate
结果返回false
,界面得不到更新。