dreamweaver网页设计形考任务一/信息流优化师工作总结
简介
正常来讲的话当我们点击组件的时候,该组件以及该组件的子组件都会重新渲染,但是如何避免子组件重新渲染呢,我们经常用memo来解决
React.memo配合useCallback缓存组件
- 父组件没有传props
const Index = ()=> {console.log('子组件刷新了');return (<div>这是子组件</div>)
}
//这里我们用react.memo对组件进行包裹,包裹一次之后react在render的过程中不会给该fiber打上更新的tag
//从而跳过更新,这个原理其实就是react.memo的第二个参数上,如果react.memo第二个参数不传递,react回默
//认给我们补充上第二个参数的逻辑,其中逻辑就是浅比较Index组件的props参数,如果相等的话默认第二个参数返
//回true,组件就会缓存了,如果不相等的话就会返回false组件就会重新打上更新的tag然后重新渲染。
const MemoIndex = React.memo(Index);const App = ()=>{const [state, setState] = useState(0);return (<div className="App"><button onClick={()=>setState(state+1)}>点我看看子组件刷新了吗</button><MemoIndex/></div>);
}
- 父组件传了state
const Index = ()=> {console.log('子组件刷新了');return (<div>这是子组件</div>)
}
//其实这Index组件不会更新的,react检测到我们不传递第二个参数的话,会把之前的props拆出来,和现在的
//props做比较 发现pre.next === cur.next 然后回返回true组件就会缓存了
const MemoIndex = React.memo(Index);
//这行代码就相当这样的代码
const MemoIndex = React.memo(Index, (pre, cur)=> {//这样写的就比较简单了,因为这是是针对于当前的demo来说的。react比较的代码逻辑比较复杂,因为react//需要考虑到多种情况,props中参数可能多一个少一个的情况,所以react默认提供的代码比较复杂if(pre.name === cur.name) {return true;}return false;
});const App = ()=>{const [state, setState] = useState(0);return (<div className="App"><button onClick={()=>setState(state+1)}>点我看看子组件刷新了吗</button><MemoIndex name={0}/></div>);
}
- 父组件传了函数
const Index = ()=> {console.log('子组件刷新了');return (<div>这是子组件</div>)
}
const MemoIndex = React.memo(Index);const App = ()=>{const [state, setState] = useState(0);const func = ()=> {};return (<div className="App">//这时候子组件会不会刷新呢,有的同学可能说不会因为浅比较发现pre.func === cur.func 返回//true所以不会刷新,但是其实是会刷新的,因为APP组件中触发了setState之后App组件重新渲染,也//就是相当于执行了App()这个方法,所以里面func的指向地址发生了变化,所以pre.func !== //cur.func 子组件会重新渲染,<button onClick={()=>setState(state+1)}>点我看看子组件刷新了吗</button><MemoIndex func={func}/></div>);
}
使用useCallback缓存函数
const Index = ()=> {console.log('子组件刷新了');return (<div>这是子组件</div>)
}const MemoIndex = React.memo(Index);const App = ()=>{const [state, setState] = useState(0);//这里我们用了useCallback,useCallback主要是缓存我们当前的函数,如果我们第二个参数传递空数组的话//他的地址不会改变,如果我们第二个参数传递的是一个变量,这个变量发生变化他的地址就会发生变化。所以这//和useEffect的第二个参数是一样的,但是请注意不要滥用useCallback的第二个参数。如果第二个参数滥用//会拿到我们之前的值。我们看下一个示例就知道了const func = useCallback(()=> {}, [])return (<div className="App"><button onClick={()=>setState(state+1)}>点我看看子组件刷新了吗</button><MemoIndex func={func}/></div>);
}
使用useMemo缓存组件
useMemo不仅可以缓存变量,函数还可以缓存组件
const Index = (props)=> {console.log('子组件刷新了');return (<div>这是子组件</div>)
}const App = ()=>{const [state, setState] = useState(0);//使用useMemo也要和useCallback一样特别注意第二个参数,因为他有可能导致我们拿不到最新的数据解决//解决方案就和useCallback的一样,简单来说套用react官方的话就是请确保数组中包含了所有外部作用域//中会随时间变化并且在useMemo中使用的变量都要放到第二个参数中。const Component = useMemo(()=><Index/>, []);return (<div className="App"><button onClick={()=>setState(state+1)}>点我看看子组件刷新了吗</button>{Component}</div>);
}
利用props.children缓存组件
这样在Index组件re-render的时候,由于App(父组件)中的组件没有变化,所以拿到的children依然是上一次的(没有发生变化的)所以children部分不会re-render。
const Index = (props)=> {const [state, setState] = useState(0);return (<div>//当这个按钮点击之后我们发现Children组件并不重新刷新了,其实原理我理解的是react帮我们做了一层//处理当渲染前与渲染后两个组件的引用地址一样他就会放弃render,当然这是我的猜测,这个的话之后//我看到源码的时候会和大家讲一下在补充一下。<button onClick={()=>setState(state+1)}>点我我看看子组件刷新不刷新</button>{props.children}</div>)
};
const Children = ()=> {return (<div>{console.log('子组件刷新了')}这是children组件</div>)
}const App = ()=>{return (<div className="App"><Index><Children/></Index></div>);
}
注意事项
- useCallBack不是每个函数都需要使用!不要滥用useCallback
const Index = (props)=> {console.log('子组件刷新了');return (<div>//点击这个按钮之前先点击App组件下面的按钮,让state变大,然后在点击这个按钮看看state是啥//我们发现state一直是一个0。这是为什么呢,因为很简单我们之前讲了useCallback第二个和//useEffect的第二个参数是一样的,因为我们传递的是空数组说以useCallback一直拿到的是最原始的//值,所以会造成这个问题,我们写代码的时候千万要注意第二个参数,只要useCallback需要什//值我们就在第二个参数传递什么值,这样才可以确保我们拿到的是最新的值。同样的里面如果不需要一些//参数的话我们也不要把这些参数加到第二个参数上面否则会出现func的地址多次改变。<button onClick={props.func}>点我看看state是啥</button>这是子组件</div>)
}
const MemoIndex = React.memo(Index);const App = ()=>{const [state, setState] = useState(0);const func = useCallback(()=> {console.log(state);}, [])return (<div className="App"><button onClick={()=>setState(state+1)}>点我看看子组件刷新了吗</button><MemoIndex func={func}/></div>);
}
- useCallBack是一个缓存工具没错。但实际上他并不能阻止函数都重现构建。
示例:
大家看上方这种结构的组件,Com组件中包含了fun1和fun2两个函数。
是不是认为当Com组件重新渲染的时候,只有fun2(没有使用useCallBack的函数)函数会被重新构建,而fun1(使用了useCallBack的函数)函数不会被重新构建。
实际上,被useCallBack包裹了的函数也会被重新构建并当成useCallBack函数的实参传入。
useCallBack的本质工作不是在依赖不变的情况下阻止函数创建,而是在依赖不变的情况下不返回新的函数地址而返回旧的函数地址。不论是否使用useCallBack都无法阻止组件render时函数的重新创建!!
每一个被useCallBack的函数都将被加入useCallBack内部的管理队列。而当我们大量使用useCallBack的时候,管理队列中的函数会非常之多,任何一个使用了useCallBack的组件重新渲染的时候都需要去遍历useCallBack内部所有被管理的函数找到需要校验依赖是否改变的函数并进行校验。
在以上这个过程中,寻找指定函数需要性能,校验也需要性能。所以,滥用useCallBack不但不能阻止函数重新构建还会增加“寻找指定函数和校验依赖是否改变”这两个功能,为项目增添不必要的负担。
//Com组件
const Com = () => {//示例1包裹了useCallBack的函数const fun1 = useCallBack(() => {console.log('示例一函数');...},[])//示例2没有包裹useCallBack的函数const fun2 = () => {console.log('示例二函数');...}return <div></div>
}
不要过度缓存组件
其实不必过度优化代码 react官方没有帮你做 其实也证明了 如果你的代码没有明显的卡顿 你自己去做优化 可能造成负优化
优化的手段一般都是针对组件本身比较复杂且数据量大每次re-render都会造成卡顿的情况下才去做的,没有太明显的卡顿出现时没必要做这些优化。而且在使用memo前其实也有手段去规避这些无效的re-render,比如将组件粒度划分的更细一些
参考文章
useCallBack你真的知道怎么用吗。
相关文章:

正确使用React组件缓存
简介 正常来讲的话当我们点击组件的时候,该组件以及该组件的子组件都会重新渲染,但是如何避免子组件重新渲染呢,我们经常用memo来解决 React.memo配合useCallback缓存组件 父组件没有传props const Index ()> {console.log(子组件刷新…...

AMEYA360:大唐恩智浦荣获 2023芯向亦庄 “汽车芯片50强”
2023年11月28日,由北京市科学技术委员会和北京市经济和信息化局指导、北京经济技术开发区管理委员会主办、盖世汽车协办的“芯向亦庄”汽车芯片大赛在北京亦庄成功闭幕。 在本次大赛中 大唐恩智浦的 电池管理芯片DNB1168 (应用于新能源汽车BMS系统) 凭卓越的性能及高…...

在Arch Linux上安装yay
有点麻烦。 准备 # pacman -Syu # pacman -S --needed base-devel git 变身为普通用户 不能使用root下载代码。所以要变身为普通用户: # sueradd tsit # su tsit 下载代码 $ git clone https://aur.archlinux.org/yay.git 编译安装 $ cd yay $ makepkg -si…...

PHP案例:探究MySQL应用开发喜好的网络调查
文章目录 一、知识准备(一)数据库与表的创建(二)录入调查选项(三)创建问卷页面(四)处理投票数据(五)显示调查结果二、实现步骤(一)创建数据库与表(二)录入若干调查选项(三)创建问卷页面(四)创建调查结果页面(五)体验运行结果(六)查看最终生成的HTML代码很…...

力扣第374场周赛题解
这一场周赛的题目是比较难的一次,写了1个多小时就写了两个题目。 首先第一题: 纯水题,遍历然后进行一下判断就可以解决了。这边就不放代码了。 第二题: 这个题目,我觉得难度非常大,其实代码量也不大都是很…...

Linux Docker 安装Nginx
1.21、查看可用的Nginx版本 访问Nginx镜像库地址:https://hub.docker.com/_/nginx 2、拉取指定版本的Nginx镜像 docker pull nginx:latest #安装最新版 docker pull nginx:1.25.3 #安装指定版本的Nginx 3、查看本地镜像 docker images 4、根据镜像创建并运行…...

鸿蒙应用开发(二)环境搭建
开发流程 IDE下载 首先下载HUAWEI DevEco Studio,介绍首次启动DevEco Studio的配置向导: 运行已安装的DevEco Studio,首次使用,请选择Do not import settings,单击OK。安装Node.js与ohpm。node.js 是基于 V8 引擎构…...

在 Qt Creator 中编写 Doxygen 风格的注释
2023年12月10日,周日上午 如何生成Doxygen 风格的注释 在需要Doxygen 风格注释的函数上方输入 /**,然后按下 Enter 键。Qt Creator 将自动为你生成一个注释模板。 输入,Qt Creator会自动帮你补全Doxygen标签 不得不说,写了Doxyge…...

NSS [NSSCTF 2022 Spring Recruit]babyphp
NSS [NSSCTF 2022 Spring Recruit]babyphp 考点:PHP特性 开局源码直接裸奔 <?php highlight_file(__FILE__); include_once(flag.php);if(isset($_POST[a])&&!preg_match(/[0-9]/,$_POST[a])&&intval($_POST[a])){if(isset($_POST[b1])&&…...

ToolkenGPT:用大量工具增强LLM
深度学习自然语言处理 原创作者:cola 用外部工具增强大型语言模型(LLM)已经成为解决复杂问题的一种方法。然而,用样例数据对LLM进行微调的传统方法,可能既昂贵又局限于一组预定义的工具。最近的上下文学习范式缓解了这一问题,但有…...

2022蓝桥杯c组求和
题目名字 求和 题目链接 题意 输入的每个数都要两两相乘,然后再加起来,求最后总和; 思路 每个数乘这个数的前缀和即可 算法一:前缀和 实现步骤 先把前缀和写出来再写for循环每个数都乘以自己的前缀和; 实现步骤 直接…...

Altium Designer学习笔记11
画一个LED的封装: 使用这个SMD5050的封装。 我们先看下这个芯片的功能说明: 5050贴片式发光二极管: XL-5050 是单线传输的三通道LED驱动控制芯片,采用的是单极性归零码协议。 数据再生模块的功能,自动将级联输出的数…...

TTS | 2019~2023年最新增强/生成情绪的语音合成调研(20231211更新版)
本博客主要是 增强/生成情绪的语音合成调研,论文按照时间顺序排列,且有些论文为期刊会议论文,有的是arxiv论文,在本文中,标识如下: 【🔊ICML 】【✨Interspeech 】【🫧ICASSP】 20…...

搜狗输入法v模式 | 爱莉希雅皮肤
搜狗输入法v模式 | 爱莉希雅皮肤 前言爱莉希雅皮肤v模式 前言 搜狗输入法有v模式,v模式是一个转换和计算的功能组合。拥有数字转换、日期转换、算式计算、函数计算等功能。本文介绍如何使用v模式,并附赠一个爱莉希雅的皮肤,可通过百度网盘下…...

2023年阿里云云栖大会-核心PPT资料下载
一、峰会简介 历经14届的云栖大会,是云计算产业的建设者、推动者、见证者。2023云栖大会以“科技、国际、年轻”为基调,以“计算,为了无法计算的价值”为主题,发挥科技平台汇聚作用,与云计算全产业链上下游的先锋代表…...

JavaScript实战:制作一个待办事项列表应用
JavaScript实战:制作一个待办事项列表应用 引言 在本教程中,我们将一步步创建一个简单的待办事项列表应用,这不仅会帮助你学习基本的JavaScript编程概念,还会教会你如何处理事件以及操作DOM。这个项目是面向初学者的,…...

4面百度软件测试工程师的面试经验总结
没有绝对的天才,只有持续不断的付出。对于我们每一个平凡人来说,改变命运只能依靠努力幸运,但如果你不够幸运,那就只能拉高努力的占比。 2023年7月,我有幸成为了百度的一名测试工程师,从外包辞职了历经1000…...

textarea文本框回车enter的时候自动提交表单,根据内容自动高度
切图网近期一个bootstrap5仿chatgpt页面的项目遇到的,textarea文本框回车enter的时候自动提交表单,根据内容自动高度,代码如下,亲测可用。 <textarea placeholder"Message ChatGPT…" name"" rows"&q…...

dubbo框架技术文档-《spring-boot整合dubbo框架搭建+配置文件》框架的本地基础搭建
阿丹: 目前流行的微服务更多的就是dubbo和springcould微服务。之前阿丹没有出过dubbo相关的文章,因为之前接触springcould的微服务概念比较多一点,但是相对于springcould来说,springcould服务之间的调用是大多是使用了nacos&#…...

中通快递单号查询入口,将指定某天签收的单号筛选出来
批量查询中通快递单号的物流信息,将指定某天签收的单号筛选出来。 所需工具: 一个【快递批量查询高手】软件 中通快递单号若干 操作步骤: 步骤1:运行【快递批量查询高手】软件,并登录 步骤2:点击主界面左…...

MySQL-含json字段表和与不含json字段表查询性能对比
含json字段表和与不含json字段表查询性能对比 说明: EP_USER_PICTURE_INFO_2:不含json字段表 20200729json_test:含有json字段表 其中20200729json_test 标准ID、MANAGER_NO、PHONE_NO 为非json字段 data为json字段 2个表中MANAGER_NO、PHONE_NO都创建了各自的索引 测试…...

如何用Docker快速搭建本地开发环境
📢 声明: 🍄 大家好,我是风筝 🌍 作者主页:【古时的风筝CSDN主页】。 ⚠️ 本文目的为个人学习记录及知识分享。如果有什么不正确、不严谨的地方请及时指正,不胜感激。 直达博主:「…...

SpringDataJPA基础
简介 Spring Data为数据访问层提供了熟悉且一致的Spring编程模版,对于每种持久性存储,业务代码通常需要提供不同存储库提供对不同CURD持久化操作。Spring Data为这些持久性存储以及特定实现提供了通用的接口和模版。其目的是统一简化对不同类型持久性存储…...

程序员如何成为自由的独立开发者?
你是不是那个整天坐在电脑前敲代码的程序员朋友?作为程序员,你是否也曾思考过如何成为一名独立开发者?思考过究竟如何踏上这段充满挑战和创造的旅程? 现在这个数码时代,技术不断演进,越来越多的程序员朋友…...

Ant Design Vue(v1.7.8)a-table组件的插槽功能
本案例中,编写了一个名为stockAdd的vue(v2.5.17)自定义组件,使用a-table组件的插槽功能,创建了一个可编辑的数据表格: 表格用于添加采购的物品,点“新增物品”按键,表格添加一行&…...

笔记69:Conv1d 和 Conv2d 之间的区别
笔记地址:D:\work_file\(4)DeepLearning_Learning\03_个人笔记\4. Transformer 网络变体 a a a a a a a a a a a...

关于马达保护器 的选型 你知道吗
一、智能马达保护器的介绍 在有色冶炼中,根据工艺需求和客户需求,智能电动机保护器的主要应用模式有保护模式、端子控制模式、全通信模式和半通信模式。 4.1保护模式 在保护模式下,智能电动机保护器只利用其自身的保护功能和测量功能&#…...

springboot(ssm高校竞赛管理系统 在线竞赛平台 Java系统
springboot(ssm高校竞赛管理系统 在线竞赛平台 Java系统 开发语言:Java 框架:ssm/springboot vue JDK版本:JDK1.8(或11) 服务器:tomcat 数据库:mysql 5.7(或8.0) 数…...

SDXL使用animateDiff和hotshot-xl进行文生视频
截至2023.12.8号,目前市面上有两款适用于SDXL的文生视频开源工具,分别是AnimateDiff和hotshot-xl。 一、工具下载链接 (1)AnimateDiff的webui版本的git链接: GitHub - continue-revolution/sd-webui-animatediff: A…...

【高数:3 无穷小与无穷大】
【高数:3 无穷小与无穷大】 1 无穷小与无穷大2 极限运算法则3 极限存在原则4 趋于无穷小的比较 参考书籍:毕文斌, 毛悦悦. Python漫游数学王国[M]. 北京:清华大学出版社,2022. 1 无穷小与无穷大 无穷大在sympy中用两个字母o表示无…...