ReactNative 进阶(三十):Component、PureComponent 解析

一、前言
React.PureComponent 与 React.Component 几乎完全相同,但 React.PureComponent 通过props和state的浅对比来实现 shouldComponentUpate()。
在PureComponent中,如果包含比较复杂的数据结构,可能会因深层的数据不一致而产生错误的否定判断,导致界面得不到更新。
如果定义了 shouldComponentUpdate(),无论组件是否是 PureComponent,它都会执行shouldComponentUpdate(),并根据结果来判断是否 update。如果组件未实现 shouldComponentUpdate() ,则会判断该组件是否是 PureComponent,如果是的话,会对新旧 props、state 进行 shallowEqual 比较,一旦新旧不一致,会触发 update。
浅对比:通过遍历对象上的键执行相等性,并在任何键具有参数之间不严格相等的值时返回 false。 当所有键的值严格相等时返回 true。
二、区别
PureComponent自带通过props和state的浅对比来实现 shouldComponentUpate(),而Component没有。
2.1 PureComponent 缺点
可能会因深层的数据不一致而产生错误的否定判断,从而shouldComponentUpdate结果返回false,界面得不到更新。
2.2 PureComponent 优势
不需要开发者自己实现shouldComponentUpdate,就可以进行简单的判断来提升性能。
2.3 问题剖析
为什么PureComponent比较复杂的数据结构,可能会因深层的数据不一致而产生错误的否定判断?JavaScript 中的对象一般是可变的(Mutable),因为使用了引用赋值,新的对象简单的引用了原始对象,改变新的对象将影响到原始对象。如 foo={a: 1}; bar=foo; bar.a=2 你会发现此时 foo.a 也被改成了 2。
为了解决这个问题,一般的做法是使用 shallowCopy(浅拷贝)或 deepCopy(深拷贝)来避免被修改,但这样做造成了 CPU 和内存的浪费。
接下来分析shallowEqual()函数
下面以组件的使用来举例:
例如:
在 MainComponent 中去修改 numbers 时,ChildComponent 并没有得到刷新。原因在于 js 使用的是引用赋值,新的对象简单引用了原始对象,改变新对象虽然影响了原始对象,但对象的地址还是一样,使用===比较的方式相等。而在PureComponent中,会被判定prop相等而不触发render()。
避免此类问题最简单的方式是,避免使用值可能会突变的属性或状态,而是使用副本来返回新的变量。
三、拓展阅读
版权声明: 本文为 InfoQ 作者【No Silver Bullet】的原创文章。
原文链接:【http://xie.infoq.cn/article/3ce2046d7c83ff5ccfe7812cc】。文章转载请联系作者。











评论