当前位置: 首页 > news >正文

react 父子组件的渲染机制 | 优化手段

文章目录

    • 父子组件的渲染机制
    • 优化手段与实践写法
      • 父组件:下发state
        • props.children 传递无状态组件
        • props传递组件
      • React.memo缓存子组件与useCallback结合

父子组件的渲染机制

渲染分初次渲染重新渲染

React组件会在两种情况下发生重新渲染

  • 当组件自身的state发生变化
  • 当组件的父组件重新渲染
    当一个父组件被触发渲染时,其所有子组件都会重新渲染(子组件的子组件也会)

但有些场景下我们并不希望所有的子组件都重新渲染,比如在一个列表中,我们只希望重新渲染单击受新选择影响的这项。

优化手段与实践写法

文章1::https://juejin.cn/post/7251861916146417723

父组件:下发state

在一个组件中,一部分组件使用了 state ,而另一部分组件和 state 相对孤立,此时可以将使用的了state的组件拆分为子组件。

优化前

// 优化前写法
const Component = () => {const [isOpen, setOpen] = useState(false)return (<div><button onClick={() => setOpen(!isOpen)}>open</button>{ isOpen && <ModalDialog />}{/* 状态的变化会引起 SlowComponent 重复渲染 */}<SlowComponent /></div>)
}

优化后
优化思路:将使用了state的组件拆分为一个子组件,state在子组件中使用(将state下发到子组件),state变化时仅当前组件重渲染。

// 优化后写法
const Component = () => {return (<div><ButtonWithDialog /><SlowComponent /></div>)
}
const ButtonWithDialog = () => {const [isOpen, setOpen] = useState(false)return (<><button onClick={() => setOpen(!isOpen)}>open</button>{ isOpen && <ModalDialog />}</>)
}
props.children 传递无状态组件

这两个方法其实思路都是一样的,就是拆分受state影响的组件与不受state影响的组件。

有时无法轻易的把一个组件单独的独立提取出来,此时可以把带状态的组件提取出来,然后把耗时的组件作为 props .children 传递。

优化前

const FullComponent = () => {const [state, setState] = useState(1);const onClick = () => {setState(state + 1);};return (<div onClick={onClick} className="click-block"><p>Click this component - "slow" component will re-render</p><p>Re-render count: {state}</p><VerySlowComponent /></div>);
};

优化后
优化思路:父组件传递props对于引用类型来说其实传递是地址,也就是在子组件中使用props引用类型其实是使用的地址值。执行父组件的render的时候,比较发现props.children的引用地址没变化。

本方法与组件形式引用的区别:组件重新渲染其实是执行render方法, 如果子组件采用组件形式引入(可以理解为这里引入的是子组件render方法的执行结果。)
每次父组件重新渲染都会执行子组件的render方法获取新的执行结果。

const SplitComponent = () => {return (<><ComponentWithClick><><p>Click the block - "slow" component will NOT re-render</p><VerySlowComponent /></></ComponentWithClick></>);
};
const ComponentWithClick = ({ children }) => {const [state, setState] = useState(1);const onClick = () => {setState(state + 1);};return (<div onClick={onClick} className="click-block"><p>Re-render count: {state}</p>{children}</div>);
};
props传递组件

该方法与props.children本质是一样的,只不过有些时候如果无法通过props.children传递,可以将组件作为props的参数传递。

优化前

const FullComponent = () => {const [state, setState] = useState(1);const onClick = () => {setState(state + 1);};return (<div onClick={onClick} className="click-block"><p>Click this component - "slow" component will re-render</p><p>Re-render count: {state}</p><VerySlowComponent /><p>Something</p><AnotherSlowComponent /></div>);
};

优化后
优化思路:props 不受状态变化的影响,所以可以避免耗时组件的重复渲染。适用于耗时组件不受状态变化的影响,又不能作为 children 属性传递

const ComponentWithClick = ({ left, right }) => {const [state, setState] = useState(1);const onClick = () => {setState(state + 1);};return (<div onClick={onClick} className="click-block"><p>Re-render count: {state}</p>{left}<p>Something</p>{right}</div>);
};// 把组件作为 props 传递给组件,这样耗时组件就不受点击事件的影响
const SplitComponent = () => {const left = (<><h3>component with slow components passed as props</h3><p>Click the block - "slow" components will NOT re-render</p><VerySlowComponent /></>);const right = <AnotherSlowComponent />;return (<><ComponentWithClick left={left} right={right} /></>);
};

React.memo缓存子组件与useCallback结合

React.memo方法是一个高阶函数,参数是一个组件A,返回包装过的新组件B。
包装过的新组件B具有缓存功能,只有组件A的props发生变化,才会触发组件重新渲染。

注意点
这里props 是浅比较,在将对象方法作为 props 传递时必须考虑到引用地址的问题(如果地址变化,也会被认为props变化了)。

解决办法
在父组件中,对于需要传递给子组件的引用类型

  • 使用useCallback缓存函数
  • 使用useMemo缓存函数返回的结果(本场景的作用是缓存对象)

比如选中的子组件高亮,父组件维护一个选中子组件的activeId
优化前写法:在子组件中对比当前Id是否与activeId一致。
点击子组件时,activeId一直变化,所以每个子组件的props会变化。

const children=({activeId,id})=>{const isActive = activeId===id;return (<div className={isActive?'active':''}></div>)
}

优化后写法
思路:缓存子组件,当props变化时才渲染。在父组件判断当前子组件是否选中的,如果选中传递className(这里可以自定义props,传递什么都行)。这样的好处是className变化的子组件才会重新渲染。

// 在父组件中使用子组件
<FolderclassName={activeId === item.id ? 'active' : ''}key={item.id}id={item.id}/>

相关文章:

react 父子组件的渲染机制 | 优化手段

文章目录 父子组件的渲染机制优化手段与实践写法父组件&#xff1a;下发stateprops.children 传递无状态组件props传递组件 React.memo缓存子组件与useCallback结合 父子组件的渲染机制 渲染分初次渲染和重新渲染 React组件会在两种情况下发生重新渲染 当组件自身的state发生…...

elementPlus el-table动态列扩展及二维表格

1、循环列数据源&#xff0c;动态生成列 <template><div><el-table ref"table" :data"pageData.tableData" stripe style"width: 100%"><el-table-column v-for"column in pageData.columns" :key"column.p…...

vitepress系列-04-规整sideBar左侧菜单导航

规整左侧菜单导航 新建navConfig.ts 文件用来管理左侧导航菜单&#xff1a; 将于其他的配置分开&#xff0c;避免config.mts太大 在config目录下&#xff0c;新建 sidebarModules文件目录用来左侧导航菜单 按模块进行分类&#xff1a; 在config下新建sidebarConfig.ts文件&…...

golang slice总结

目录 概述 一、什么是slice 二、slice的声明 三、slice的初始化、创建 make方式创建 创建一个包含指定长度的切片 创建一个指定长度和容量的切片 创建一个空切片 创建一个长度和容量都为 0 的切片 new方式创建 短声明初始化切片 通过一个数组来创建切片 声明一个 …...

MySQL 数据库的优化

目录 一. 常见故障 单实例常见故障 1. 故障一 2. 故障二 3.故障三 4. 故障四 5. 故障五 6.故障六 7.故障七 8.故障八 主从环境常见故障 1.故障一 2. 故障二 3. 故障三 二. 优化 1.硬件方面 1.1 关于CPU 1.2 关于内存 1.3 关于磁盘 2. 配置文件优化 关于引擎…...

Redis 的主从复制、哨兵和cluster集群

目录 一. Redis 主从复制 1. 介绍 2. 作用 3. 流程 4. 搭建 Redis 主从复制 安装redis 修改 master 的Redis配置文件 修改 slave 的Redis配置文件 验证主从效果 二. Redis 哨兵模式 1. 介绍 2. 原理 3. 哨兵模式的作用 4. 工作流程 4.1 故障转移机制 4.2 主节…...

Unity进阶之路(2)UI Toolkit

UI Toolkit是Unity内置的一个游戏UI解决方案。借鉴了web前端的设计模式。 web前端使用css&#xff0c;html&#xff0c;js。 其中css定义样式 html定义层级 js处理逻辑 UI Toolkit则是使用uss&#xff0c;uxml&#xff0c;C# 如果直接使用Unity提供的可视化UI创建工具创建…...

实现Hello Qt 程序

&#x1f40c;博主主页&#xff1a;&#x1f40c;​倔强的大蜗牛&#x1f40c;​ &#x1f4da;专栏分类&#xff1a;QT❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、使用 "按钮" 实现 1、纯代码方式实现 2、可视化操作实现 &#xff08;1&#xff09…...

若依 ruoyi-vue 接口挂载获取Resources静态资源文件权限校验

解决小程序图片打包过大&#xff0c;放置后端&#xff0c;不引用ngnix、minio等组件&#xff0c;还能进行权限校验 package com.huida.web.controller.common.app;import com.huida.common.core.controller.BaseController; import com.huida.common.utils.file.FileUtils; imp…...

【STM32嵌入式系统设计与开发】——16InputCapture(输入捕获应用)

这里写目录标题 STM32资料包&#xff1a; 百度网盘下载链接&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1mWx9Asaipk-2z9HY17wYXQ?pwd8888 提取码&#xff1a;8888 一、任务描述二、任务实施1、工程文件夹创建2、函数编辑&#xff08;1&#xff09;主函数编辑&#…...

「论文阅读」还在手写Prompt,自动Prompt搜索超越人类水平

每周论文阅读笔记&#xff0c;来自于2023LARGE LANGUAGE MODELS ARE HUMAN-LEVEL PROMPT ENGINEERS code:https://github.com/keirp/automatic_prompt_engineer 手写prompt确实很费脑筋&#xff0c;但其实本身大语言模型就是一个很好的自动prompt工具&#xff0c;APE文章提出自…...

安全测试概述和用例设计

一、安全测试概述 定义&#xff1a;安全测试是在软件产品开发基本完成时&#xff0c;验证产品是否符合安全需求定义和产品质量标准的过程。 概念&#xff1a;安全测试是检查系统对非法侵入渗透的防范能力。 准则&#xff1a;理论上来讲&#xff0c;只要有足够的时间和资源&a…...

JavaScript 超详细学习思路

JavaScript 是一种轻量级的编程语言&#xff0c;它可以在网页中嵌入&#xff0c;用来实现网页的动态效果和用户交互功能。它是 Web 开发中不可或缺的一部分&#xff0c;与 HTML 和 CSS 并称为 Web 技术的三大基石。下面我会根据您的要求&#xff0c;对每个部分进行详细的讲解。…...

LeetCode:1483. 树节点的第 K 个祖先(倍增 Java)

目录 1483. 树节点的第 K 个祖先 题目描述&#xff1a; 实现代码与解析&#xff1a; 倍增 原理思路&#xff1a; 1483. 树节点的第 K 个祖先 题目描述&#xff1a; 给你一棵树&#xff0c;树上有 n 个节点&#xff0c;按从 0 到 n-1 编号。树以父节点数组的形式给出&#…...

ConstraintLayout在复杂布局中,出现卡顿问题解决记录

ConstraintLayout在画界面的过程中&#xff0c;确实带来了不少的方便&#xff0c;随着使用的越来越多&#xff0c;也发现了一些问题&#xff0c;特此记录一下问题和解决方案。 在背景为图片&#xff0c;而背景图片宽度固定高度自适应的情况下&#xff0c;布局显示在图片固定位…...

责任链模式详解+代码案例

责任链设计模式 定义&#xff1a; 又名职责链模式&#xff0c;为了避免请求发送者与多个请求处理者耦合在一起&#xff0c;将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链&#xff1b;当有请求发生时&#xff0c;可将请求沿着这条链传递&#xff0c;直到…...

如何让Webots支持C#语言开发的控制器

Webots支持C、C、Java、Python、Matlab这五种语言开发控制器&#xff0c;没有直接支持C#&#xff0c;但有个同事已经用C#写了大量的机器人控制代码&#xff0c;想在不把C#代码改写成C的情况下&#xff0c;直接用webots仿真&#xff0c;那就得想想办法。(不过&#xff0c;让Chat…...

如何将本地仓库放到远程仓库中

在我们仓库创建好之后&#xff0c;我们复制好ssh 接着我们需要使用git remote add<shortname><url>这个命令 shortname就是我们远程仓库的别名 接着使用git remote -v这个命令查看一下目前远程仓库的别名和地址 原本还有一个指令git branch -M main 指定分支的名…...

Jedis-事务

一&#xff0c;Jedis 我们要使用Java来操作Redis Jedis是Redis官方推荐的java连接工具。使用Java操作Redis的中间件。如果你要使用Java操作redis&#xff0c;那么一定要对jedis十分的熟悉 二&#xff0c;idea 连接jedis 1&#xff0c;导入jar包 <dependencies><depen…...

智慧安防监控EasyCVR视频调阅和设备录像回看无法自动播放的原因排查与解决

智慧安防监控EasyCVR视频管理平台能在复杂的网络环境中&#xff0c;将前端设备统一集中接入与汇聚管理。国标GB28181协议视频监控/视频汇聚EasyCVR平台可以提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级联、磁盘阵列存储、视频集中存储、…...

百元不入耳蓝牙耳机哪个好?必入五款高性价比产品

喜欢听歌的朋友都会遇到一个常见问题&#xff0c;长时间戴耳机容易导致耳朵不适&#xff0c;甚至疼痛难忍。这种情况下&#xff0c;要是不听音乐反而感到不舒服&#xff0c;真是让人苦恼&#xff0c;仿佛音乐与耳机无法和谐共存。但是&#xff0c;难道就没有一款既舒适又让人心…...

android APP monkey 测试

monkey 测试 一、电脑ADB安装及使用详解1、什么是 Monkey 测试2、什么是ADB3、ADB的作用4、安装前提条件5、ADB下载6、ADB安装与配置 二、连接安卓手机检查是否连接上安卓手机windows端安装ADB驱动 三、 monkey测试操作指令演示指令APP包名查看方式测试效果 一、电脑ADB安装及使…...

IMBoy缓存系统深度解析:为何选择depcache而非ETS或Redis

在IMBoy即时通讯平台的开发过程中&#xff0c;我们面临了选择最佳缓存系统的关键技术决策。经过细致的考量&#xff0c;我们选择了depcache作为IMBoy的核心缓存机制。本文将阐述IMBoy缓存系统的选型理由&#xff0c;并对比分析depcache与纯ETS方案及Redis方案的不同优势。 1. …...

Twitter Api查询用户粉丝列表

如果大家为了获取实现方式代码的话可能要让大家失望了&#xff0c;这边文章主要是为了节省大家开发时间&#xff0c;少点坑。https://api.twitter.com/2/users/:id/followers &#xff0c;这个接口很熟悉吧&#xff0c;他是推特提供的获取用户关注者&#xff08;粉丝&#xff0…...

深入理解计算机系统 家庭作业 2.96

题目出的很不好,感觉没有标准. #include <stdio.h>typedef unsigned float_bits;int float_f2i(float_bits f) {unsigned sign f >> (31);unsigned exp (f >> 23) & 0xff;unsigned frac f & 0x7fffff;unsigned add (frac & 0x3) 0x3;unsig…...

主函数if __name__ == ‘__main__‘:

在Python中&#xff0c;主函数通常指的是脚本的入口点&#xff0c;也就是当你直接运行一个Python脚本时&#xff0c;会首先执行的函数。在大多数Python脚本中&#xff0c;主函数并不是通过main()这样的函数名来定义的&#xff0c;而是通过检查脚本是作为模块导入还是被直接运行…...

34.Python从入门到精通—Python3 正则表达式检索和替换

34.从入门到精通&#xff1a;Python3 正则表达式检索和替换 repl 参数是一个函数 正则表达式对象 正则表达式修饰符 - 可选标志 正则表达式模式* 正则表达式实例 检索和替换repl 参数是一个函数正则表达式对象正则表达式修饰符 - 可选标志正则表达式模式*正则表达式实例 检索和…...

springboot 反射调用ServiceImpl时报错:java.lang.NullPointerExceptio、,mapper为null【解决方法】

springboot 反射调用ServiceImpl时报错&#xff1a;java.lang.NullPointerException、mapper为null【解决方法】 问题描述问题分析解决方案创建SpringBootBeanUtil编写调用方法 executeMethod调用 总结 问题描述 在使用Spring Boot时&#xff0c;我们希望能够通过反射动态调用…...

内网安全之域内密码喷洒

域内密码喷洒一般和域内用户名枚举一起使用&#xff0c;可以在无域内凭据的情况下&#xff0c;通过枚举出域内存在的用户名&#xff0c;进而对域内存在的用户名进行密码喷洒&#xff0c;以此来获得域内有效凭据。 在Kerberos协议认证的AS-REQ阶段&#xff0c;请求包cname对应的…...

何为HTTP状态码?一文清楚基本概念。

在客户端与服务器之间的信息传输过程中&#xff0c;我们可以将其比喻为客户与快递员之间的包裹传递。那么服务器是如何通知客户端&#xff0c;操作是成功还是失败&#xff1f;或者有其他的一些情况呢&#xff1f;&#xff08;就像客户可以查询快递的状态&#xff09; 而这背后…...

租赁模板建站 网站的名称归属/西安网站建设公司排行榜

机器学习模型分生成式模型&#xff08;Generative Models&#xff09;和判别式模型(Discriminative Models)。判别式模型就是给出一个判断&#xff0c;比如是哪个类别&#xff0c;是多少值。也就是说&#xff0c;判别式模型给出的是一个值。为什么需要生成式模型&#xff1f;因…...

响应式网站是什么意思/全国免费发布信息平台

转自eoe社区 每一个Tab对应了一个布局&#xff0c;这个就有点好玩了。一个Activity&#xff0c;对应了多个功能布局。①新建一个Tab项目&#xff0c;注意&#xff0c;不要生成main Activity这里不要选②在包里面新建一个类MyTab&#xff0c;继承于TabActivity其实&#xff0c;T…...

美术学院网站建设/整站优化 快速排名

Codeforces Round #779 (Div. 2&#xff09;简训导语涉及的知识点题目A Marin and PhotoshootB Marin and Anti-coprime PermutationC Shinju and the Lost PermutationD1 388535 (Easy Version)D2 388535 (Hard Version)参考文献导语 两道&#xff0c;菜 涉及的知识点 数学…...

镇海企业建站/360推广登陆

来自对https://jalammar.github.io/visualizing-neural-machine-translation-mechanics-of-seq2seq-models-with-attention/的笔记 注意力机制核心观点就是让RNN每一步都监视一个更大的信息集合并从中挑选信息。例如&#xff1a;如果你使用RNN去为一个图像生成注释&#xff0c;…...

java 现代网站开发/网站推广途径和推广要点有哪些?

华夏之声-证券大本营链接:http://media.cnr.cn/来自 “ ITPUB博客 ” &#xff0c;链接&#xff1a;http://blog.itpub.net/39335/viewspace-350757/&#xff0c;如需转载&#xff0c;请注明出处&#xff0c;否则将追究法律责任。 转载于:http://blog.itpub.net/39335/viewspa…...

网站备案核验系统/新冠疫苗接种最新消息

出差是不少员工的工作常态&#xff0c;尤其对于那些从事产品销售、运维等工作的员工而言&#xff0c;出差更是家常便饭。一般而言&#xff0c;对公司的合理安排&#xff0c;员工应当服从。然而&#xff0c;如果公司明知员工不适宜出差&#xff0c;却仍然频繁作出异地出差的工作…...