React里的浅比较
React里的浅比较
react的PureComponent类的shouldComponentUpdate方法使用了浅比较来判断props和state是否发生变化,一些组件可以通过继承PureComponent来优化组件性能,减少不必要的re-render。但是有些组件即使继承了PureComponent也没有任何性能上的改变。我们来看看浅比较的原理。
1 | const hasOwnProperty = Object.prototype.hasOwnProperty; |
以上是react中浅比较的部分源码。is
方法是es6中Object.is
方法的实现,我理解主要是为了兼容低版本浏览器。
Object.is()
方法能很好的对基本类型的数据进行比较,并且不会出现==
时的类型转换,也不会产生NaN!==NaN
为true的以及-0 == +0
的情况。
1 | Object.is(null, undefined);//false |
当比较的两个值满足下列情况时,Object.is()
方法返回true:
- 都是
undefined
- 都是
null
- 都是
true
或者false
- 都是由相同字符组成的相同长度的字符串
- 指向的都是同一个对象
- 都是数字,并且
- 都是+0
- 都是-0
- 都是非0且非NaN的相同值的数字
以上情况在比较的时候就会返回true。可以看出,Object.is()
方法弥补了==
和===
比较的缺陷。
下面逐步解读一下shallowEqual
方法。
1 | const hasOwnProperty = Object.prototype.hasOwnProperty; |
通过上面的代码的可以看出(尤其最后一段),当传入参数是对象时__浅比较只会进入到对象的第一层__,如果参数对象的属性值仍然是对象,这时候是不会递归进入到属性值内部去比较的;如果参数对象前后指向的是不同的引用,即使引用所指向对象的内部属性值都是一样,shallowEqual返回的结果仍会是false。如果想此时仍能使用PureComponent达到性能优化的结果,则必须保证传入参数所指向的都是同一个引用。
综上,PureComponent有性能优化的功能,前提是组件接收的props或者组件内部的state结构比较简单。如果props或者state嵌套比较深(有两层及以上的嵌套),则可能就没法通过shallowEqual比较出变化,这也是有些组件使用了PureComponent后没有发现有任何性能上的优化的原因。