RN底层原理 -- 1. Component和PureComponent解析

1.前言

1. React.PureComponent与React.Component几乎完全相同,
   但React.PureComponent通过props和state的浅对比来实现
   shouldComponentUpdate()
   
2. 在PureComponent中,如果包含比较复杂的数据结构,可能会因深层的数据不一致而产生错误的否定判断,导致界面得不到更新。

3. 如果定义了shouldComponentUpdate(),无论组件是否是PureComponent,
   它都会执行shouldComponentUpdate(),并根据结果来判断是否update界面。
   如果组件未实现shouldComponentUpdate(),则会判断该组件是否是PureComponent,
   如果是PureComponent,会对新、旧props、state进行shallowEqual比较
   (shallow: 浅的 <---->  deep: 深的)
   
4. 浅对比
   通过遍历对象上的键值是否相等,当键值不等返回false
   当所有键的值相等时返回true

二、区别

PureComponent自带通过props和state的浅对比来实现shouldComponentUpdate()
而Component没有
 1. PureComponent的缺点
 可能会因为深层的数据不一致而产生错误的否定判断,从而shouldComponentUpdate
 结果返回false,界面不会更新
 2. PureComponent优势
 不需要开发者自己实现shouldComponentUpdate,就可以进行简单的判断来提升性能

  • 底层原因
  1. JavaScript中的对象一般是可变的(Mutable),因为使用了引用赋值,新的对象简单的引用了原始对象,改变新的对象将影响到原始对象。
  2. 简单来说,就是指针引用,两个变量指向的地址是相同的。这也是浅拷贝机制。
  • 分析shallowEqual()函数

function shallowEqual(objA, objB) -> boolean {
	// 1.首先判断是否相等,相等返回true
	// 这里就会存在漏洞了,如果浅拷贝一个数组对象,对象地址指向这里
	// 就算修改了数组中的内容,但是地址是不会变的
	// 那么用浅拷贝的对象和原来的对象去对比,会发现:
	// 1. 虽然数组的内容发送了变化
	// 2. 但是两个对象的地址是同一个,就会认为相等了,导致误判断
	if (objA === objB) {
		return true;
	}
	
	// 2. 如果不相等,obj为空或不为object类型,返回false
	// 为空了,或者不为object了,肯定也是不相等
	if (typeof objA !== 'object' || objA === null ) || (typeof objB !== 'object' || objB === null) {
		return false;
	}
	
	// 3. 获取obj的keys集合,如果两者的长度不相等,就返回false
	// 长度都不相等,两者肯定不相等
	let keysA = Object.keys(objA)
	let keysB = Object.keys(objB)
	if (keysA.length !== keysB.length) {
		return false
	}
	
	// 4. 循环遍历
	// 如果长度相等,就挨个key进行比较
	// 如果另一个obj不含有key, 返回false
	// 如果两个obj的key的值不相等,也返回false
	for (const key of keysA) {
		if (!objB.hasOwnProperty(key) || objA[key] !== objB[key]) {
			return false
		}
	}
	
	// 5. 能来到这里,就返回true
	return true
}
  • 解决方法
    要用深拷贝,三个点的语法,对原来的对象深拷贝,这样地址就不一样了
  this.setState(prevState => ({
    numbers: [...prevState.numbers, 1],
  }));
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值