文章目录

  • Component和PureComponent的区别
    • 介绍
    • 区别点:
      • PureComponent缺点
      • PureComponent优势
    • 为什么PureComponent比较复杂的数据结构,可能会因深层的数据不一致而产生错误的否定判断?

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。shallowEqual

区别点:

  1. PureComponent自带通过props和state的浅对比来实现 shouldComponentUpate(),而Component没有。

PureComponent缺点

  1. 可能会因深层的数据不一致而产生错误的否定判断,从而shouldComponentUpdate结果返回false,界面得不到更新。

PureComponent优势

  1. 不需要开发者自己实现shouldComponentUpdate,就可以进行简单的判断来提升性能。

为什么PureComponent比较复杂的数据结构,可能会因深层的数据不一致而产生错误的否定判断?

JavaScript 中的对象一般是可变的(Mutable),因为使用了引用赋值,新的对象简单的引用了原始对象,改变新的对象将影响到原始对象。如 foo={a: 1}; bar=foo; bar.a=2 你会发现此时 foo.a 也被改成了 2。

为了解决这个问题,一般的做法是使用 shallowCopy(浅拷贝)或 deepCopy(深拷贝)来避免被修改,但这样做造成了 CPU 和内存的浪费。

let foo = {a: {b: 1}};
let bar = foo;
bar.a.b = 2;
console.log(foo.a.b);  // 打印 2
console.log(foo === bar); // 打印 true

可以在fb的shallowEqual方法源码中看到,如下,浅对比只是用Object.is()对Object的value做了一个基本数据类型的比较。


function is(x: mixed, y: mixed): boolean {// SameValue algorithmif (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 redundantreturn x !== 0 || y !== 0 || 1 / x === 1 / y;} else {// Step 6.a: NaN == NaNreturn x !== x && y !== y;}
}function shallowEqual(objA: mixed, objB: mixed): boolean {if (is(objA, objB)) {return true;}if (typeof objA !== 'object' || objA === null ||typeof objB !== 'object' || objB === null) {return false;}const keysA = Object.keys(objA);const keysB = Object.keys(objB);if (keysA.length !== keysB.length) {return false;}// Test for A's keys different from B.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;
}

我们先来对is()函数进行分析:

在js中 ‘===’ 可以判断数据类型是否相等,但其实这样方式也并不十分严谨,例如

+0 === -0; // js 打印true
NaN === NaN; // js 打印false

我们希望上述的判断结果,+0和-0为false,NaN与NaN为true,这时候可以用这种方式

1/+0 // 结果为Infinity
1/-0 // 结果为-Infinity
Infinity === -Infinity; // false解决 NaN === NaN为false,可以通过NaN和自身不相等的特性来解决
x !== x && y !== y

所以is()函数首先是通过 ‘===’ 来对数据类型进行比较,然后解决+0/-0和NaN的比较问题。

接下来分析shallowEqual()函数

function shallowEqual(objA: mixed, objB: mixed): boolean {// 首先对两个基本数据类型进行比较if (is(objA, objB)) {return true;}// 判断两个数据都为object的情况if (typeof objA !== 'object' || objA === null ||typeof objB !== 'object' || objB === null) {return false;}// 获得所有的keyconst keysA = Object.keys(objA);const keysB = Object.keys(objB);// 判断两者key的数量是否一致if (keysA.length !== keysB.length) {return false;}// 如果key数量相同,使用一层for循环去比较for (let i = 0; i < keysA.length; i++) {if (// 判断对象B中是否包含对象A的key,即两者的keys是否一致!hasOwnProperty.call(objB, keysA[i]) ||// 通过is()函数对比A和B的key对应的数据!is(objA[keysA[i]], objB[keysA[i]])) {return false;}}

下面以组件的使用来举例:

例如:

class ChildComponent extends React.PureComponent {render() {return(<div>{this.props.numbers}</div>)}
}
class MainComponent extends React.Component {constructor(props) {super(props);this.handleClick = this.handleClick.bind(this);this.state = {numbers: [0]}}handleClick() {const arr = this.state.numbers;arr.push(1);this.setState({numbers: arr})console.log(this.state.numbers)}render() {<div><button onClick={this.handleClick} /><ChildComponent numbers={this.state.numbers}/></div>}
}

然而在MainComponent中去修改numbers时,ChildComponent并没有得到刷新。原因在于js使用的是引用赋值,新的对象简单引用了原始对象,改变新对象虽然影响了原始对象,但对象的地址还是一样,使用===比较的方式相等。而在PureComponent中,会被判定prop相等而不触发render()。

避免此类问题最简单的方式是,避免使用值可能会突变的属性或状态,而是使用副本来返回新的变量。

handleClick() {this.setState(prevState => ({words: [...prevState.words, 'marklar'],}));
};

另外一种方式是使用Immutable.js

Component和PureComponent的区别相关推荐

  1. [转]ExtJs基础--Html DOM、Ext Element及Component三者之间的区别

    要学习及应用好Ext框架,必须需要理解Html DOM.Ext Element及Component三者之间的区别. 每一个HTML页面都有一个层次分明的DOM树模型,浏览器中的所有内容都有相应的DOM ...

  2. [react] 解释下react中component和pureComponent两者的区别是什么?

    [react] 解释下react中component和pureComponent两者的区别是什么? 组件的state或者props更新都会触发render(),同时也会导致子组件render()重新渲 ...

  3. React.Component与React.PureComponent的区别

    转发自:https://blog.csdn.net/qq_29854831/article/details/79657718 React.PureComponent 与 React.Component ...

  4. React Native之组件Component与PureComponent

    众所周知,React Native的页面元素是由一个一个的组件所构成的,这些组件包括系统已经提供的组件,如View.TextInput等,还有一些第三方库提供的组件,以及自定义的组件.通常在封装组件的 ...

  5. Spring:@Configuration和@Component的使用与区别

    1.美图 2.概述 spring常用注解 @Component 大家都不陌生,用来注解一些公共的服务类. 但是Spring boot 中的注解 @Configuration 有什么用呢?两者有什么区别 ...

  6. @Component和@Bean的区别

    最近学习spring的时候,一直搞不清这两个的区别,网上写的是在太官方了,小白太难了.于是自己整理一下. 首先,相同点,这两者目的都是注册bean到spring中因此都可以通过@Autowried装配 ...

  7. java合集系列之pring@Component @Repository@Service的区别

    问题 在spring集成的框架中,注解在类上的@Component,@Repository,@Service等注解能否被互换?或者说这些注解有什么区别? 回答1 引用spring的官方文档中的一段描述 ...

  8. reac组件,Component 与 PureComponent

    我们可以看到react提供了两种组件的类型,一开始学习的时候都是使用Component,但是React提供了另外一个 PureComponent, 纯组件,目的是: 优化渲染 import React ...

  9. @Component 和 @Bean 的区别

    Spring帮助我们管理Bean分为两个部分,一个是注册Bean,一个装配Bean. 完成这两个动作有三种方式,一种是使用自动配置的方式.一种是使用JavaConfig的方式,一种就是使用XML配置的 ...

最新文章

  1. 【C语言学习趣事】_GCC源代码分析_2_assert.h
  2. CTOR在区块熵编码中的优点
  3. 浅析phpwind9.0之登陆机制
  4. Android实用笔记——使用Spinner实现下拉列表
  5. 新工科背景下的大数据体系建设探析
  6. URL传递中文、Ajax传递中文,Java如何编码如何解决乱码
  7. 智能一代云平台(二十四):已安装的Nginx上安装echo插件
  8. 自定义View----滑动刻度尺与流式布局 实例(四)
  9. mysql各存储引擎介绍表格_十六、MySQL基础系列笔记之数据表存储引擎的介绍
  10. UNICODE,GBK,UTF-8区别
  11. 笔记本双网卡带宽叠加上网
  12. PVAJP计划:暨关于.Press全站使用VUE-AJAX-JSON-PYTHON的新规划
  13. SSM整合(idear)
  14. vue怎么给pc端浏览器设置一个最小屏幕_图文讲解uni-app的PC宽屏适配方案
  15. 最强赛亚人服务器维护,最强赛亚人官方,最强赛亚人手游官方正版预约 v1.1.0-手游汇...
  16. 2017互联网月饼哪家强?腾讯、阿里、百度、网易等21家中秋月饼盘点
  17. VMware虚拟机安装及Linux系统的配置
  18. ElasticStack:使用FileBeat、Logstash、Elasticsearch、Kibana收集清洗存储查看分析数据
  19. 00 | 基础编程题目集题解传送门
  20. css中的background属性

热门文章

  1. poll机制读取按键值
  2. C6000汇编语言实现乘法,C6000(四)-汇编.ppt
  3. 数学物理方程与特殊函数—分离变量法
  4. 家居企业怎么做微信营销?
  5. JS判断是苹果系统(ios)还是安卓系统(Android)或者PC端
  6. ICG-PEG-NHS,吲哚菁绿PEG活性酯,ICG-PEG2000-NHS
  7. C++ ostream的学习
  8. php 语法错误,PHP语法错误?
  9. 【前端】Vue+Element UI案例:通用后台管理系统-代码总结(已开源)
  10. 音频管理器录制设备_如何同时从多个音频设备录制