浅比较
在官方文档性能优化里有这么一说: The problem is that PureComponent will do a simple comparison between the old and new values of this.props.words. Since this code mutates the words array in the handleClick method of WordAdder, the old and new values of this.props.words will compare as equal, even though the actual words in the array have changed. The ListOfWords will thus not update even though it has new words that should be rendered.
意思就是在确定是否重新渲染组件,是根据 props 和 state 的是否变化来判断,但判断它俩是否相同,只是简单比较了一下,如果是一些嵌套对象 什么的就没办法准确比较
在 React 中有一个 shouldComponentUpdate,用于根据 state 是否变化来判断是否需要更新(render)组件,如果 state 没有变化,那么就不重新渲染组件,否则渲染组件,有了这样一个判断逻辑,那么程序在运行的时候必然能减少一大部分多余的性能开销。
浅比较源码 shallowEqual
const hasOwnProperty = Object.prototype.hasOwnProperty;
/**
* Performs equality by iterating through keys on an object and returning false
* when any key has values which are not strictly equal between the arguments.
* Returns true when the values of all keys are strictly equal.
*/
function shallowEqual(objA: mixed, objB: mixed): boolean {
// 调用Object.is判断是否相等,相同返回true,不同返回false; 只能判断完 全相等值和对象地址
if (Object.is(objA, objB)) {
return true;
}
// object.is比较发现不等,但并不代表真的不等,object对象还需要比较
// 这里判断是否是object,如果不是,那直 接返回false
if (
typeof objA !== "object" ||
objA === null ||
typeof objB !== "object" ||
objB === null
) {
return false;
}
const keysA = Object.keys(objA);
const keysB = Object.keys(objB);
// 比较对象中的keys长度,不等返回false
if (keysA.length !== keysB.length) {
return false;
}
// 比较对象中相同的key的val是否相等
for (let i = 0; i < keysA.length; i++) {
if (
!hasOwnProperty.call(objB, keysA[i]) || // 判断在objB中是否有objA中的所有key,比较key是否相同
!Object.is(objA[keysA[i]], objB[keysA[i]]) // 判断同key的value是否相同
) {
// 一旦有一个属性值没有或有一对属性,不是完全相等值或同地址对象
// 则不等
return false;
}
}
return true;
}
// 浅比较函数
// 比较了props和nextProps,state和nextState
function shallowCompare(instance, nextProps, nextState) {
return (
!shallowEqual(instance.props, nextProps) ||
!shallowEqual(instance.state, nextState)
);
}