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

2024-02-16 18:48

本文主要是介绍ReactNative进阶(三十):Component、PureComponent 解析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 一、前言
    • 二、区别
      • 2.1 PureComponent 缺点
      • 2.2 PureComponent 优势
      • 2.3 问题剖析
    • 三、拓展阅读


一、前言

React.PureComponentReact.Component 几乎完全相同,但 React.PureComponent 通过propsstate的浅对比来实现 shouldComponentUpate()

PureComponent中,如果包含比较复杂的数据结构,可能会因深层的数据不一致而产生错误的否定判断,导致界面得不到更新。

如果定义了 shouldComponentUpdate(),无论组件是否是 PureComponent,它都会执行shouldComponentUpdate(),并根据结果来判断是否 update。如果组件未实现 shouldComponentUpdate() ,则会判断该组件是否是 PureComponent,如果是的话,会对新旧 propsstate 进行 shallowEqual 比较,一旦新旧不一致,会触发 update

浅对比:通过遍历对象上的键执行相等性,并在任何键具有参数之间不严格相等的值时返回false。 当所有键的值严格相等时返回true。

二、区别

PureComponent自带通过propsstate的浅对比来实现 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()函数

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()函数对比AB的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 => ({numbers: [...prevState.numbers, 1],}));
};

三、拓展阅读

  • 《ReactNative专栏》

这篇关于ReactNative进阶(三十):Component、PureComponent 解析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/715379

相关文章

JavaScript中的reduce方法执行过程、使用场景及进阶用法

《JavaScript中的reduce方法执行过程、使用场景及进阶用法》:本文主要介绍JavaScript中的reduce方法执行过程、使用场景及进阶用法的相关资料,reduce是JavaScri... 目录1. 什么是reduce2. reduce语法2.1 语法2.2 参数说明3. reduce执行过程

C语言中自动与强制转换全解析

《C语言中自动与强制转换全解析》在编写C程序时,类型转换是确保数据正确性和一致性的关键环节,无论是隐式转换还是显式转换,都各有特点和应用场景,本文将详细探讨C语言中的类型转换机制,帮助您更好地理解并在... 目录类型转换的重要性自动类型转换(隐式转换)强制类型转换(显式转换)常见错误与注意事项总结与建议类型

MySQL 缓存机制与架构解析(最新推荐)

《MySQL缓存机制与架构解析(最新推荐)》本文详细介绍了MySQL的缓存机制和整体架构,包括一级缓存(InnoDBBufferPool)和二级缓存(QueryCache),文章还探讨了SQL... 目录一、mysql缓存机制概述二、MySQL整体架构三、SQL查询执行全流程四、MySQL 8.0为何移除查

在Rust中要用Struct和Enum组织数据的原因解析

《在Rust中要用Struct和Enum组织数据的原因解析》在Rust中,Struct和Enum是组织数据的核心工具,Struct用于将相关字段封装为单一实体,便于管理和扩展,Enum用于明确定义所有... 目录为什么在Rust中要用Struct和Enum组织数据?一、使用struct组织数据:将相关字段绑

使用Java实现一个解析CURL脚本小工具

《使用Java实现一个解析CURL脚本小工具》文章介绍了如何使用Java实现一个解析CURL脚本的工具,该工具可以将CURL脚本中的Header解析为KVMap结构,获取URL路径、请求类型,解析UR... 目录使用示例实现原理具体实现CurlParserUtilCurlEntityICurlHandler

深入解析Spring TransactionTemplate 高级用法(示例代码)

《深入解析SpringTransactionTemplate高级用法(示例代码)》TransactionTemplate是Spring框架中一个强大的工具,它允许开发者以编程方式控制事务,通过... 目录1. TransactionTemplate 的核心概念2. 核心接口和类3. TransactionT

数据库使用之union、union all、各种join的用法区别解析

《数据库使用之union、unionall、各种join的用法区别解析》:本文主要介绍SQL中的Union和UnionAll的区别,包括去重与否以及使用时的注意事项,还详细解释了Join关键字,... 目录一、Union 和Union All1、区别:2、注意点:3、具体举例二、Join关键字的区别&php

Spring IOC控制反转的实现解析

《SpringIOC控制反转的实现解析》:本文主要介绍SpringIOC控制反转的实现,IOC是Spring的核心思想之一,它通过将对象的创建、依赖注入和生命周期管理交给容器来实现解耦,使开发者... 目录1. IOC的基本概念1.1 什么是IOC1.2 IOC与DI的关系2. IOC的设计目标3. IOC

java中的HashSet与 == 和 equals的区别示例解析

《java中的HashSet与==和equals的区别示例解析》HashSet是Java中基于哈希表实现的集合类,特点包括:元素唯一、无序和可包含null,本文给大家介绍java中的HashSe... 目录什么是HashSetHashSet 的主要特点是HashSet 的常用方法hasSet存储为啥是无序的

Linux中shell解析脚本的通配符、元字符、转义符说明

《Linux中shell解析脚本的通配符、元字符、转义符说明》:本文主要介绍shell通配符、元字符、转义符以及shell解析脚本的过程,通配符用于路径扩展,元字符用于多命令分割,转义符用于将特殊... 目录一、linux shell通配符(wildcard)二、shell元字符(特殊字符 Meta)三、s