React Native 性能优化组件-PureComponent

栏目: IOS · Android · 发布时间: 5年前

内容简介:在React里,shouldComponentUpdate源码为:可以看到PureComponent就是对props跟state的前后状态做了一个浅比较。看看shallowEqual的源码:

在React里,shouldComponentUpdate源码为:

if (this._compositeType === CompositeTypes.PureClass) {  
  shouldUpdate = !shallowEqual(prevProps, nextProps) || !shallowEqual(inst.state, nextState);
}
复制代码

可以看到PureComponent就是对props跟state的前后状态做了一个浅比较。

看看shallowEqual的源码:

const hasOwn = Object.prototype.hasOwnPropertyfunctionis(x, y) {
  if(x === y) {
    returnx !==0 || y !==0 ||1/ x ===1/ y  
} else {
    returnx !== x && y !== y  
  }
}
export default function shallowEqual (objA, objB) {
  if ( is(objA, objB )) 
    return true
  i f( typeofobjA !=='object' || objA === null || typeofobjB !=='object' || objB   ===null) {
    return false
}
const keysA = Object.keys ( objA )
const keysB = Object.keys ( objB )
if  (  keysA.length !== keysB.length)
  return false
for ( leti =0; i < keysA.length; i++) {
    if ( !hasOwn.call ( objB, keysA[i] )  || !is(objA[keysA[i]], objB[keysA[i]])) {
      return false
    }  
  }
return true
}
复制代码

Object.is ()

在解析 shallowEqual 的源码之前,先来认识一下 Object.is() ,这个函数是用来比较两个值是否相等。

为什么要用这个来比较而不是 == 或者 === 呢?

==

首先先看 == ,由于 JS 是弱类型的,如果使用 == 进行比较, == 操作符会自动将 0,‘’(空字符串),null,undefined 转成布尔型 false ,这样就会出现

0==' '// true
null==undefined// true
[1] ==true// true
复制代码

这显然是不符合预期的。所以 JS 为我们提供了全等操作符 === ,它不会进行类型转换,也就是说如果两个值一样,必须符合类型也一样。但是,它还是有两种疏漏的情况

+0 === -0//true,但我们期待它返回falseNaN===NaN//false,我们期待它返回true
复制代码

所以, Object.is() 修复了 `=== 这两种判断不符合预期的情况,

function (x, y){
  // SameValue algorithm
  if(x === y) {
    // 处理为+0 != -0的情况
    returnx !==0 || 1/ x ===1/ y;    
  } else {
    // 处理 NaN === NaN的情况
    return x !== x && y !== y;    
  }
};
复制代码

这样就使得 Object.is() 总是返回我们需要的结果。 它在下面6种情况下,会返回 true

  • 两个值都是 undefined
  • 两个值都是 null
  • 两个值都是 true 或者都是 false
  • 两个值是由相同个数的字符按照相同的顺序组成的字符串
  • 两个值指向同一个对象
  • 两个值都是数字并且
    +0
    -0
    
  • 都是 NaN
  • 都是除零和 NaN 外的其它同一个数字

可以看出 Object.is 可以对基本数据类型: null,undefined,number,string,boolean 做出非常精确的比较,但是对于引用数据类型是没办法直接比较的。

剖析 shallowEquall

// 用原型链的方法
const hasOwn = Object.prototype.hasOwnProperty
// 这个函数实际上是 Object.is() 的 polyfill
functionis (x, y) {
  if (x === y) {
    returnx !==0 || y !==0 ||1/ x === 1/ y  
  } else {
    returnx !== x && y !== y  
  }
} 
export default function shallowEqual (objA, objB) {
  // 首先对基本数据类型的比较
  if (is(objA, objB))
    return true
  // 由于 Obejct.is() 可以对基本数据类型做一个精确的比较, 所以如果不等
  // 只有一种情况是误判的,那就是 object, 所以在判断两个对象都不是 object
  // 之后,就可以返回 false 了
  if (typeofobjA !== 'object' || objA === null || typeofobjB !== 'object' || objB ===null ) {
    return false
  }
  // 过滤掉基本数据类型之后,就是对对象的比较了
  // 首先拿出 key 值,对 key 的长度进行对比 
  const keysA = Object.keys( objA)
  const keysB = Object.keys(objB)  
  // 长度不等直接返回 false 
  if (keysA.length !== keysB.length)
    return false
  // key 相等的情况下,在去循环比较
  for  (let i =0; i < keysA.length; i++) {
    // key值相等的时候
    // 借用原型链上真正的 hasOwnProperty 方法,判断ObjB里面是否有A的key的key值
    // 属性的顺序不影响结果也就是 {name:'daisy', age:'24'} 跟 {age:'24',name:'daisy' } 是一样的
    // 最后,对对象的value进行一个基本数据类型的比较,返回结果
    if( !hasOwn.call(objB, keysA[i])  || !is(objA[keysA[i]], objB[keysA[i]])){
      return false
     }  
  }
  return true
}
复制代码

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

运营有道:重新定义互联网运营

运营有道:重新定义互联网运营

李明轩 / 机械工业出版社 / 2017-7-31 / 69.00元

本书是前百度资深运营专家多年运营经验的总结,是作者运营千万级用户规模的大型互联网产品的实操经验复盘,是作者在“在行”上为近百位CEO和高管提供互联网运营咨询服务后对互联网运营需求的深入洞见。 本书的思想基础是“运营必须以用户为中心”,从产品、用户、市场3个维度对互联网运营重新进行了系统性的梳理:从道的层面解读并重新定义运营方法论,从术的层面围绕方法论提出行之有效的解决方法和实际案例。重点不在......一起来看看 《运营有道:重新定义互联网运营》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

在线进制转换器
在线进制转换器

各进制数互转换器

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具