react中PureComponent浅对比策略
PureComponent实现了Component中没有实现的shouComponentUpdata()方法,会对state和props进行一次浅对比,本文介绍一下浅对比策略
源码中,实现浅对比的函数是:shallowEqual(),源码:
//shouldComponentUpdate 源码: 判断是不是PureReactComponent,是的话,返回shallowEqual() if (ctor.prototype && ctor.prototype.isPureReactComponent) { return ( !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState) ); }
// shallowEqual方法源码: const hasOwnProperty = Object.prototype.hasOwnProperty; // 这个is函数,处理了基本类型对比。 function is(x, y) { // 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; } } /** * 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 { if (is(objA, objB)) { return true; } // 由于Obejct.is()可以对基本数据类型做一个精确的比较, 所以如果不等 // 只有一种情况是误判的,那就是object,所以在判断两个对象都不是object // 之后,就可以返回false了 if ( typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null ) { return false; } // 过滤掉基本数据类型之后,就是对对象的比较了 // 首先拿出key值,对key的长度进行对比 const keysA = Object.keys(objA); const keysB = Object.keys(objB); if (keysA.length !== keysB.length) { return false; } /// key值相等的时候 // 借用原型链上真正的 hasOwnProperty 方法,判断ObjB里面是否有A的key的key值 // 属性的顺序不影响结果也就是{name:'daisy', age:'24'} 跟{age:'24',name:'daisy' }是一样的 // 最后,对对象的value进行一个基本数据类型的比较,返回结果 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; } export default shallowEqual;