PureComponent和Component的区别和底层处理机制

news/2024/10/30 9:35:47/

PureComponentComponent都是React中的组件类,但它们在实现细节和使用上有些差别。

Component是React中定义组件的基类,它的shouldComponentUpdate方法默认返回true,也就是说,每次调用setStateforceUpdate方法都会引发组件重新渲染。如果我们希望在一些情况下避免不必要的渲染(例如propsstate没有变化),就需要在继承自Component的组件中手动实现shouldComponentUpdate方法来进行比较。

PureComponent则提供了一种基于浅比较的优化机制,它默认实现了shouldComponentUpdate方法,会自动对组件的propsstate进行浅比较,如果发现propsstate没有发生变化,则阻止组件的重新渲染,提高性能。对于复杂的数据结构,需要注意进行引用类型的比较,避免误判。

底层处理机制
PureComponentComponent的区别在于对shouldComponentUpdate方法的处理。在React内部实现中,当调用setStateforceUpdate方法时,会触发更新过程,有以下几个步骤:

1.修改组件的state和props;
2.调用组件的shouldComponentUpdate方法,决定是否需要重新渲染组件;
3.如果需要重新渲染组件,React会根据虚拟DOM的增量更新算法计算出需要更新的节点,并将变化应用到DOM上。

因此,PureComponentComponent的区别在于第2步的处理机制。对于PureComponent,会在默认实现的shouldComponentUpdate方法中自动进行浅比较propsstate,从而判断是否需要重新渲染组件;而对于Component,则需要手动实现shouldComponentUpdate方法来进行比较。

需要注意的是,虽然PureComponent的默认实现可以避免一些不必要的渲染,但它并不是完全自动化的,也不能保证在所有情况下都能正确地避免不必要的渲染。在实际应用中,还需要根据具体情况来选择合适的组件类来达到最佳的性能和开发效率。

理解浅比较

在这里插入图片描述

function isObject(obj) {return obj !== null && typeof obj === 'object';
}function shallowEqual(objA, objB) {if (Object.is(objA, objB)) {return true;}if (!isObject(objA) || !isObject(objB)) {return false;}const keysA = Reflect.ownKeys(objA);const keysB = Reflect.ownKeys(objB);if (keysA.length !== keysB.length) {return false;}for (let i = 0; i < keysA.length; i++) {const key = keysA[i];if (!objB.hasOwnProperty(key) || !Object.is(objA[key], objB[key])) {return false;}}return true;
}

注意

1.这里为什么用Object.is,因为我们这里认为nan等于nan,所以我们要用 这个方法!
2.如果我们的浅比较无法导致更新,那么我们可以通过this. forceUpdate(); //跳过默认加的shouldComponentUpdate, 直接更新

如果使用Component但是没有自己实现shouldComponentUpdate怎么办?

如果没有自己实现shouldComponentUpdate方法,Component会默认返回true,也就是每次调用setState或者forceUpdate都会导致组件的重新渲染,甚至在组件的propsstate没有变化时也会重新渲染。

这在一些情况下可能会导致性能问题,因此我们可以通过以下两种方式来优化组件的性能:

手动实现shouldComponentUpdate方法,对组件的属性进行比较,避免不必要的重新渲染。例如,在props或者state没有变化时,返回false,否则返回true。在比较属性时,我们可以使用浅比较或者深比较来实现,具体方法取决于属性的数据类型和结构。一般来说,如果属性比较简单,我们可以使用浅比较,否则可以使用第二种方式。

使用React.memo高阶组件对组件进行包装,将组件包装成具有浅比较优化功能的组件。React.memo的作用是对组件的props进行浅比较,如果props没有变化,则不会重新渲染组件。使用React.memo的方式非常简单,只需要将组件作为React.memo的参数传入即可,例如:

import React, { memo } from 'react';const MyComponent = ({ name, age }) => {return (<div><span>Name: {name}</span><span>Age: {age}</span></div>);
};export default memo(MyComponent);

http://www.ppmy.cn/news/312134.html

相关文章

javassist 入门以及dubbo中的使用案例

javassite 入门 概述原理 简单的demo记录方法执行的时间带参数和返回值javassite 占位符 dubbo中的使用代理工厂 JavassistProxyFactory代理类 org.apache.dubbo.common.bytecode.Proxyorg.apache.dubbo.rpc.proxy.InvokerInvocationHandler创建类的工具类 ClassGenerator 概述…

x宝评论抓取

#某宝评论接口sign参数逆向 1.接口速览 多次请求发现&#xff0c;t为时间戳&#xff0c;sign为加密参数&#xff0c;盲猜和data、t有关&#xff0c;sign为32位&#xff0c;盲猜是字符串的32位的MD5 2.搜索js代码 这里为搜索的是appKey&#xff0c;就找到了sign&#xff0c;然…

知识变现海哥:值得反复思考的20句知识变现精华

哈喽&#xff0c;大家好&#xff0c;我是海哥&#xff0c;知识付费变现创业教练&#xff0c;教育公司培训总监&#xff0c;从事知识付费变现咨询10年&#xff0c;已助力3000人实现知识付费变现。 拉开人与人差距的有时不是转业和努力&#xff0c;而是一开始的认知和思维。 从…

16 进制转 10 进制

#include <stdio.h> //16进制转10进制 int main() {int a;printf("请输入16进制数:");scanf("%x",&a);//%x代表16进制printf("转换为10进制:");printf("%d",a);//%d带代表整形输出return 0; } &#xff05;d整型&#xff0c…

10进制数转16进制

已知&#xff1a;十进制数123被转换为十六进制数7B。这个转换过程如下&#xff1a;将123除以16&#xff0c;余数为11&#xff08;十六进制的B&#xff09;商为7.继续将7除以16&#xff0c;余数为7&#xff0c;商为0.因此7B就是123的十六进制数。 //10进制数转16进制System.out…

16进制转10进制

问题描述   从键盘输入一个不超过8位的正的十六进制数字符串&#xff0c;将它转换为正的十进制数后输出。   注&#xff1a;十六进制数中的10~15分别用大写的英文字母A、B、C、D、E、F表示。 样例输入 FFFF 样例输出 65535 求解 NO.1 思路&#xff1a;16进制转2进制&#…

windows10卸载Xshell6 报错-1603安装时出现致命错误(亲测有效)

1、报错如下图&#xff1a; 2、解决办法 1、在命令行窗口输入regedit打开注册表编辑器 2、找到 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control 3、将 RegistrySizeLimit&#xff08;REG_DWORD类型的&#xff09; 的值改为 FFFFFFFF &#xff08;10进制就是 4294967295…

10进制转16进制

问题描述   十六进制数是在程序设计时经常要使用到的一种整数的表示方式。它有0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F共16个符号&#xff0c;分别表示十进制数的0至15。十六进制的计数方法是满16进1&#xff0c;所以十进制数16在十六进制中是10&#xff0c;而十进制的17在十六进制…