react 杂记2 优化hook

useEffect

每个Fiber节点都会为该组件的所有effec对象​维护一个链表,

场景​类组件方法函数组件等效写法差异说明
挂载时执行componentDidMount()useEffect(fn, [])useEffect 副作用在浏览器绘制后异步执行;componentDidMount 是同步的。
更新时执行componentDidUpdate()useEffect(fn, [deps])useEffect 可精确控制依赖项,避免不必要的更新;componentDidUpdate 需手动比较 prevProps/prevState。
​卸载时清理componentWillUnmount()useEffect(() => { return cleanupFn }, [])清理逻辑通过返回值实现,更集中
同步 DOM 操作componentDidMount/UpdateuseLayoutEffectuseLayoutEffect 同步执行,类似类组件生命周期; useEffect 是异步的,不会阻塞页面渲染
性能优化shouldComponentUpdate()React.memo + useMemo/useCallback函数组件通过缓存值和函数减少不必要的渲染,而非直接控制更新

useEffect vs useLayoutEffect​

hook执行时机适用场景
useEffect在浏览器完成本次页面布局和绘制后,消费effect链表。大多数副作用(如 API 请求、事件订阅)。
useLayoutEffect在DOM更新后、浏览器绘制前,消费effect链表,会阻塞本次渲染。需同步读取或修改 DOM(如调整元素尺寸/位置)。

常见场景

useEffect(() => { return cleanupFn }, []) 
仅挂载时执行, cleanupFn 清理函数 ,会下一次挂载会 调用 cleanupFn
  • 事件监听与清理
useEffect(() => {const handleResize = () => {setWindowSize(window.innerWidth);};window.addEventListener('resize', handleResize);return () => window.removeEventListener('resize', handleResize);
}, []);
  • 关闭第三方库实例
useEffect(() => {const chart = d3.select('#chart').append('svg')// 初始化图表...// 清理函数:销毁图表实例return () => {chart.remove();console.log('图表已销毁');};
}, []);

ref

在这里插入图片描述


useMemo

用于缓存属性,避免重新渲染时不必要的计算,从而优化性能。
有点像vue的计算属性

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
  • ​参数:

    • ​计算函数:返回需要缓存的值(函数内部包含高开销计算)。
    • 依赖数组:当数组中的值发生变化时,重新执行计算函数。
  • ​返回值:缓存的值(依赖未变化时直接返回上一次结果)。

使用场景:

  1. 高开销计算,(如数据转换、大数组遍历),使用 useMemo 避免每次渲染重复计算
  2. 当父组件传递对象/数组给子组件时,用 useMemo 保持引用稳定,避免子组件不必要重渲染

误用场景
缓存简单计算,(字符串拼接、简单数学运算)无需缓存,useMemo 自身开销可能超过计算成本。


useCallback

用于缓存函数实例,避免渲染时的重新创建,从而优化性能。

const memoizedCallback = useCallback(() => {// 需要缓存的函数逻辑doSomething(a, b);},[a, b]) // 依赖项数组;
  • ​参数:
    • 第一个参数:需要缓存的函数。
    • 第二个参数:依赖项数组。当依赖项变化时,函数会重新创建;否则复用之前的实例。
  • ​返回值:一个持久化(缓存)的函数引用

使用场景

  1. 优化子组件渲染(配合 React.memo)​
// 父组件
const Parent = () => {const [count, setCount] = useState(0);// 使用 useCallback 缓存回调函数const handleClick = useCallback(() => {console.log("按钮被点击");}, []); // 空依赖数组:函数不依赖任何变量,始终保持同一引用return (<div><button onClick={() => setCount(c => c + 1)}>父组件计数:{count}</button>{/* 子组件因 handleClick的 引用不变,避免了因setCount的变化而重新渲染 */}<Child onClick={handleClick} /></div>);
};// 子组件用 React.memo 优化,依赖 props 的浅比较
const Child = React.memo(({ onClick }) => {console.log("子组件渲染");return <button onClick={onClick}>子组件按钮</button>;
});

⚠️ 🆘:在简单组件中,函数创建的开销可能微乎其微,优化可能得不偿失。极少特定场景适用。


React.memo()

React.memo 有点像类组件的 shouldComponentUpdata 函数,只有当props 变化时,才会重新渲染组件,否则复用。

const MyComponent = React.memo(function MyComponent(props) {// 组件逻辑
}, arePropsEqual?);
  • MyComponent:需要优化的函数组件。
  • arePropsEqual(可选):自定义的 props 比较函数。默认情况下,React.memo 会对 props 进行浅比较。如果提供了此函数,React 会使用它来判断 props 是否相等

⚠️:注意

  1. 默认浅比较: 如果 props 中包含复杂对象或数组,可能需要自定义比较函数。
  2. useMemo 和 useCallback :如果 props 中包含函数或复杂对象,建议配合 useMemo 或 useCallback 使用,以避免不必要的重新渲染
  3. 并不总是必要的,过度使用可能会增加代码复杂度。只有在性能确实成为问题时才使用。

HOC 高阶组件

是一种设计模式,它通过接受一个组件并返回一个增强后的新组件来实现逻辑复用。

  1. ​控制渲染流程
  2. 逻辑复用
  3. 增强组件功能
  4. 类组件转函数组件

定义

// js高阶函数示例:接受一个函数,返回一个新函数
const withLogger = (func) => {return (...args) => {console.log("函数被调用,参数:", args);return func(...args);};
};

使用

const add = (a, b) => a + b;
const addWithLog = withLogger(add);
addWithLog(2, 3); // 输出日志并返回 5

react中的HOC

  1. ​权限控制
const withAuth = (WrappedComponent) => {return (props) => {const isAuthenticated = true; // 权限校验逻辑return isAuthenticated ? <WrappedComponent {...props} /> : <Redirect to="/login" />;};
};export default withAuth(UserDashboard); //导出给其他组件用
  1. 类组件转函数组件。
class child extends React.Component {return div
}const ProxyComponent =  (comp) => {// Do somethingreturn function HOC(props) {// 代理为函数组件后就能 函数式接受参数return <comp {...props}>}
}export default ProxyComponent(child)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/38783.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java内存泄漏、CPU飙升排查

在Java应用开发中&#xff0c;内存泄漏和CPU飙升是两类高频出现的生产问题&#xff0c;也是常见的面试问题。这里通过一些demo进行实践。 内存泄漏 private static List<byte[]> leakList new ArrayList<>();GetMapping("/memory/leak") public void …

【搜索】dfs(回溯、剪枝、记忆化)

个人主页&#xff1a;Guiat 归属专栏&#xff1a;我讲你听 文章目录 1. dfs 回溯1.1 回溯介绍1.2 回溯模板1.3 回溯经典题目 2. dfs 剪枝2.1 剪枝介绍2. 2 剪枝模板2.3 经典题目 3. dfs 记忆化3.1 记忆化介绍3.2 记忆化示例 正文 1. dfs 回溯 1.1 回溯介绍 核心思想&#xff…

emWin自定义键盘布局

emWin V6.46提供了自带的键盘控件&#xff0c;用起来功能还是比较齐全的。但是有些时候自带的布局不能满足要求&#xff0c;此时可用键盘的结构体来自定义布局。 KEYDEF_KEYBOARD MyNumPad;static KEYDEF_AREA NumPadKeyArea[4] {{10, 0, 720, 250}, //每行按钮的坐标和占用…

人工智能之数学基础:瑞利商与特征值的关系

本文重点 瑞利商是线性代数中的一个重要概念,具有丰富的性质和广泛的应用。通过求解瑞利商的最大值或最小值,可以找到矩阵的特征值和特征向量,进而解决降维、聚类、优化和计算机视觉等领域的问题。广义瑞利商作为瑞利商的推广形式,在机器学习和数据分析中也发挥着重要作用…

Mysql配套测试之更新篇

&#x1f3dd;️专栏&#xff1a;Mysql_猫咪-9527的博客-CSDN博客 &#x1f305;主页&#xff1a;猫咪-9527-CSDN博客 “欲穷千里目&#xff0c;更上一层楼。会当凌绝顶&#xff0c;一览众山小。” 目录 测试准备&#xff1a; 更新测试 &#xff1a; 1.将孙悟空同学的数学成…

2025年如何避免使用验证码求解器时被IP封禁

引言 2025年&#xff0c;验证码求解器已成为自动化网络抓取和其他在线流程的关键工具。然而&#xff0c;自动化用户面临的一个常见挑战是IP封禁。当网站检测到自动化活动时&#xff0c;通常会阻止发出请求的IP地址&#xff0c;导致验证码挑战无法解决。本文将探讨使用验证码求…

ElasticSearch 可观测性最佳实践

ElasticSearch 概述 ElasticSearch 是一个开源的高扩展的分布式全文检索引擎&#xff0c;它可以近乎实时的存储、检索数据&#xff1b;本身扩展性很好&#xff0c;可以扩展到上百台服务器&#xff0c;处理 PB 级别&#xff08;大数据时代&#xff09;的数据。ES 也使用 Java 开…

操作系统的特征

并发 指两个或多个事件在同一时间间隔内发生。这些时间宏观上是同时发生的&#xff0c;但微观上是交替发生的。 并行 指两个或多个事件在同一时刻同时发生 操作系统的并发性 指计算机系统重“同时”运行着多个程序&#xff0c;这些程序宏观上看是同时运行的&#xff0c;而…

数据结构——B树、B+树、哈夫曼树

目录 一、B树概念1.B树的构造2 .B树的特点 二、B树概念1.B树构造2.B树的特点 三、B树和B树的区别四、哈夫曼树1.哈夫曼树的基本概念2.哈夫曼树的构建 一、B树概念 B树的出现是为了弥合不同的存储级别之间的访问速度上的巨大差异&#xff0c;实现高效的 I/O。平衡二叉树的查找效…

电子签的法律效力、业务合规与监管难点

撰稿 | 区长 来源 | 贝多财经 据2025年央视“3.15”晚会报道&#xff0c;借贷宝、人人信等平台上存在高利贷的情形。放贷人与借款人在平台签署借款合同&#xff0c;但是实际借款金额低于合同金额&#xff0c;从而绕开平台对利率的限制。这引发了人们对电子签法律效力、业务合…

资金管理策略思路

详细描述了完整交易策略的实现细节&#xff0c;主要包括输入参数、变量定义、趋势判断、入场与出场条件、止损与止盈设置等多个方面。 输入参数&#xff08;Input&#xff09;&#xff1a; EntryFrL (.6)&#xff1a;多头入场的前一日波动范围的倍数。 EntryFrS (.3)&#xff1…

体育直播视频源格式解析:M3U8 vs FLV

在体育直播领域&#xff0c;视频源的格式选择直接影响着直播的流畅度、画质以及兼容性。目前&#xff0c;M3U8 和 FLV 是两种最为常见的视频流格式&#xff0c;它们各有优劣&#xff0c;适用于不同的场景。本文将从技术原理、优缺点以及应用场景等方面对 M3U8 和 FLV 进行详细解…

【动态规划】下降路径最小和

跟之前不同由于可能取到最右上角值&#xff0c;则左右各加一列&#xff0c;并且由于求最小值&#xff0c;则加的列须设置为正无穷大&#xff1b; class Solution { public:int minFallingPathSum(vector<vector<int>>& matrix) {int nmatrix.size();vector<…

07_GRU模型

GRU模型 双向GRU笔记:https://blog.csdn.net/weixin_44579176/article/details/146459952 概念 GRU&#xff08;Gated Recurrent Unit&#xff09;也称为门控循环单元&#xff0c;是一种改进版的RNN。与LSTM一样能够有效捕捉长序列之间的语义关联&#xff0c;通过引入两个&qu…

VScode

由于centos停止了维护 ,后面使用ubuntu 在Ubuntu中用vscode 充当记事本的作用 替代了centos中vim的作用 后面使用vscode编辑 vscode中继续使用makefile , xshell中的cgdb进行debug (半图形写 ,半命令行debug&&运行) 官网下载地址&#xff1a;https://code.visuals…

【行驶证识别】批量咕嘎OCR识别行驶证照片复印件图片里的文字信息保存表格或改名字,基于QT和腾讯云api_ocr的实现方式

项目背景 在许多业务场景中,如物流管理、车辆租赁、保险理赔等,常常需要处理大量的行驶证照片复印件。手动录入行驶证上的文字信息,像车主姓名、车辆型号、车牌号码等,不仅效率低下,还容易出现人为错误。借助 OCR(光学字符识别)技术,能够自动识别行驶证图片中的文字信…

异步编程与流水线架构:从理论到高并发

目录 一、异步编程核心机制解析 1.1 同步与异步的本质区别 1.1.1 控制流模型 1.1.2 资源利用对比 1.2 阻塞与非阻塞的技术实现 1.2.1 阻塞I/O模型 1.2.2 非阻塞I/O模型 1.3 异步编程关键技术 1.3.1 事件循环机制 1.3.2 Future/Promise模式 1.3.3 协程&#xff08;Cor…

python-selenium 爬虫 由易到难

本质 python第三方库 selenium 控制 浏览器驱动 浏览器驱动控制浏览器 推荐 edge 浏览器驱动&#xff08;不容易遇到版本或者兼容性的问题&#xff09; 驱动下载网址&#xff1a;链接: link 1、实战1 &#xff08;1&#xff09;安装 selenium 库 pip install selenium&#…

前端OOM内存泄漏如何排查?

前言 现代前端开发中&#xff0c;随着应用的复杂性和交互性的增加&#xff0c;OOM&#xff08;Out Of Memory&#xff0c;内存不足&#xff09;问题和内存泄漏逐渐成为影响用户体验和应用性能的关键挑战。排查和解决这些问题需要开发人员具备良好的调试技巧和优化策略。 造成…

C++20:玩转 string 的 starts_with 和 ends_with

文章目录 一、背景与动机二、string::starts_with 和 string::ends_with&#xff08;一&#xff09;语法与功能&#xff08;二&#xff09;使用示例1\. 判断字符串开头2\. 判断字符串结尾 &#xff08;三&#xff09;优势 三、string_view::starts_with 和 string_view::ends_w…