React 生命周期与 Hook:从原理到实战全解析
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。
持续学习,不断总结,共同进步,为了踏实,做好当下事儿~
非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨
💖The Start💖点点关注,收藏不迷路💖 |
📒文章目录
- 1. React 生命周期方法详解
- 1.1 生命周期的三个阶段(挂载、更新、卸载)
- 1.2 关键生命周期方法的作用
- 1.3 不推荐使用的遗留生命周期方法
- 2. Hook 的引入与核心概念
- 2.1 为什么需要 Hook?
- 2.2 常用 Hook 及其作用
- useState - 状态管理
- useEffect - 副作用处理
- 进阶Hook示例:
- 2.3 Hook 的规则与最佳实践
- 3. 生命周期与 Hook 的对比与迁移
- 3.1 类组件生命周期 vs. Hook 实现
- 3.2 迁移策略
- 3.3 性能优化对比
- 4. 总结
React 生命周期与 Hook 是每个 React 开发者必须掌握的核心概念。理解它们的工作原理和适用场景,能帮助开发者编写更高效、可维护的组件代码。本文将深入解析类组件的生命周期方法,对比函数组件中 Hook 的工作机制,并探讨如何合理选择这两种开发模式。
1. React 生命周期方法详解
1.1 生命周期的三个阶段(挂载、更新、卸载)
React 类组件的生命周期可以分为三个主要阶段:
class ExampleComponent extends React.Component {constructor(props) {super(props); // 挂载阶段开始this.state = { count: 0 };}componentDidMount() {console.log('组件已挂载');}shouldComponentUpdate(nextProps, nextState) {return nextState.count !== this.state.count; // 更新阶段控制}componentDidUpdate() {console.log('组件已更新');}componentWillUnmount() {console.log('组件即将卸载'); // 卸载阶段}render() {return <div>{this.state.count}</div>;}
}
-
挂载阶段:组件实例被创建并插入DOM
constructor()
→render()
→componentDidMount()
-
更新阶段:组件因props或state变化而重新渲染
shouldComponentUpdate()
→render()
→componentDidUpdate()
-
卸载阶段:组件从DOM中移除
componentWillUnmount()
1.2 关键生命周期方法的作用
-
componentDidMount:
- 最佳实践:在这里进行AJAX请求、DOM操作或订阅事件
componentDidMount() {fetch('/api/data').then(res => res.json()).then(data => this.setState({ data }));this.timerID = setInterval(() => this.tick(), 1000); }
-
shouldComponentUpdate:
- 性能优化关键:通过返回true/false控制是否重新渲染
shouldComponentUpdate(nextProps, nextState) {// 仅当count变化时才更新return nextState.count !== this.state.count; }
-
componentWillUnmount:
- 清理工作:避免内存泄漏
componentWillUnmount() {clearInterval(this.timerID);this.subscription.unsubscribe(); }
1.3 不推荐使用的遗留生命周期方法
React 16.3+ 标记为不安全的生命周期方法:
componentWillMount
→ 使用constructor
或componentDidMount
替代componentWillReceiveProps
→ 使用static getDerivedStateFromProps
componentWillUpdate
→ 使用getSnapshotBeforeUpdate
替代方案示例:
static getDerivedStateFromProps(props, state) {if (props.value !== state.prevValue) {return {prevValue: props.value,// 其他派生状态...};}return null;
}
2. Hook 的引入与核心概念
2.1 为什么需要 Hook?
类组件存在三大痛点:
- 状态逻辑难以复用:HOC和render props导致"嵌套地狱"
- 复杂组件难以理解:相关逻辑分散在不同生命周期
- 类语法困惑:
this
绑定问题和class的复杂性
函数组件的局限性:
- 无法使用state
- 不能执行副作用
- 缺乏生命周期控制
2.2 常用 Hook 及其作用
useState - 状态管理
function Counter() {const [count, setCount] = useState(0);return (<div><p>You clicked {count} times</p><button onClick={() => setCount(count + 1)}>Click me</button></div>);
}
useEffect - 副作用处理
useEffect(() => {// 相当于 componentDidMount + componentDidUpdatedocument.title = `You clicked ${count} times`;return () => {// 相当于 componentWillUnmountconsole.log('cleanup');};
}, [count]); // 仅在count变化时执行
进阶Hook示例:
const theme = useContext(ThemeContext); // 上下文访问const [state, dispatch] = useReducer(reducer, initialState); // 复杂状态管理const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]); // 性能优化
2.3 Hook 的规则与最佳实践
-
调用规则:
- 只在React函数的最顶层调用Hook
- 不要在循环、条件或嵌套函数中调用
-
自定义Hook:
function useWindowWidth() {const [width, setWidth] = useState(window.innerWidth);useEffect(() => {const handleResize = () => setWidth(window.innerWidth);window.addEventListener('resize', handleResize);return () => window.removeEventListener('resize', handleResize);}, []);return width;
}
// 使用:const width = useWindowWidth();
- 性能优化:
- 使用
useCallback
缓存函数 - 使用
useMemo
缓存计算结果
- 使用
3. 生命周期与 Hook 的对比与迁移
3.1 类组件生命周期 vs. Hook 实现
生命周期方法 | Hook 等效实现 |
---|---|
constructor | useState 初始化 |
componentDidMount | useEffect(() => {}, []) |
componentDidUpdate | useEffect(() => {}, [deps]) |
componentWillUnmount | useEffect 的清理函数 |
shouldComponentUpdate | React.memo + useMemo |
3.2 迁移策略
逐步替换示例:
- 将class改为function
- 用useState替换this.state
- 用useEffect替换生命周期方法
- 用useContext替换contextType
逻辑复用对比:
// HOC方式
const EnhancedComponent = withHOC(BaseComponent);// Hook方式
function useCustomLogic() {const [value, setValue] = useState(null);// ...逻辑return value;
}
function Component() {const value = useCustomLogic();// ...
}
3.3 性能优化对比
类组件优化:
class OptimizedComponent extends React.PureComponent {// 自动浅比较props和state
}
函数组件优化:
const MemoizedComponent = React.memo(function MyComponent(props) {/* 使用props渲染 */},(prevProps, nextProps) => {/* 自定义比较逻辑 */}
);function Parent() {const memoizedCallback = useCallback(() => {doSomething(a, b);}, [a, b]);const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
}
4. 总结
-
核心对比:
- 类组件:命令式的生命周期控制
- Hook:声明式的副作用管理
-
适用场景:
- 维护旧项目:继续使用类组件
- 新项目开发:优先使用函数组件+Hook
-
学习建议:
- 理解两者原理,而非死记API
- 从简单组件开始实践Hook
- 逐步重构复杂类组件
-
未来趋势:
- React官方推荐Hook作为主要开发方式
- 新特性(如并发模式)将优先支持Hook
- 社区生态逐渐转向Hook优先
通过深入理解生命周期和Hook的关系,开发者可以更灵活地选择适合场景的开发模式,编写更清晰、更易维护的React代码。
🔥🔥🔥道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙
💖The Start💖点点关注,收藏不迷路💖 |
💖The Start💖点点关注,收藏不迷路💖 |
相关文章:

React 生命周期与 Hook:从原理到实战全解析
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 持续学习,不断…...
OpenSSL 与 C++ 搭建一个支持 TLS 1.3 的服务器
好的,我们可以使用 OpenSSL 与 C 搭建一个支持 TLS 1.3 的服务器。下面是: ✅ 一、完整示例代码(基于 OpenSSL) 使用 C 和 OpenSSL 创建一个简单的 TCP TLS 服务器,支持 TLS 1.3。 ✅ 代码:tls_server.cp…...
HOW - 简历和求职面试宝典(六)
文章目录 1. 如何更好地认识自己?一、认清自己的实力二、明确求职方向三、认识求职岗位与自己的匹配度2. 如何判断公司是否合适自己?一、网站平台二、内部人员三、通过面试官1. 如何更好地认识自己? 一、认清自己的实力 我们经常会听到这样的话:我现在的工作做的好不开心…...

【机器学习基础】机器学习入门核心算法:逻辑回归(Logistic Regression)
机器学习入门核心算法:逻辑回归(Logistic Regression) 一、算法逻辑1.1 基本概念1.2 Sigmoid函数1.3 决策边界 二、算法原理与数学推导2.1 概率建模2.2 损失函数推导2.3 梯度下降优化2.4 正则化处理 三、模型评估3.1 常用评估指标3.2 ROC曲线…...
深入理解设计模式之命令模式
下面是一篇关于设计模式之命令模式(Command Pattern)的详细博客,并附有 Java 实现代码示例。 深入理解设计模式之:命令模式(Command Pattern) 一、什么是命令模式? 命令模式(Comma…...

智能仓储落地:机器人如何通过自动化减少仓库操作失误?
仓库作业的速度和准确性至关重要,尤其是在当前对无差错、高效作业的要求达到前所未有的环境下。每一个错误,无论是物品放错位置还是库存差异,都会在供应链中产生连锁反应,造成延误、增加成本,并最终影响客户满意度。 …...
Android 架构演进之路:从 MVC 到 MVI,拥抱单向数据流的革命
在移动应用开发的世界里,架构模式的演进从未停歇。从早期的 MVC 到后来的 MVP、MVVM,每一次变革都在尝试解决前一代架构的痛点。而今天,我们将探讨一种全新的架构模式 ——MVI(Model-View-Intent),它借鉴了…...

[低代码表单生成器设计基础]ElementUI中Layout布局属性Form表单属性详解
Layout 布局 ElementUI 的 Layout 布局系统基于 24 栏栅格设计,提供了灵活的响应式布局能力,适用于各种页面结构的构建。(CSDN) 📐 基础布局结构 ElementUI 的布局由 <el-row>(行)和 <el-col>࿰…...
数据结构7——二叉树
一、二叉树的定义与性质 1.定义 首先是树形结构,每个节点最多有2棵树,二叉树的子树有左右之分,不能颠倒。 2.性质 (1)二叉树的第i层,最多有2的(i-1)次幂。 (2)深度为k࿰…...

从“被动养老”到“主动健康管理”:平台如何重构代际关系?
在老龄化与数字化交织的背景下,代际关系的重构已成为破解养老难题的关键。 传统家庭养老模式中,代际互动多表现为单向的“赡养-被赡养”关系。 而智慧养老平台的介入,通过技术赋能、资源整合与情感连接,正在推动代际关系向“协作…...
Java 中的 synchronized 和 Lock:如何保证线程安全
Java 中的 synchronized 和 Lock:如何保证线程安全 引言 在 Java 多线程编程中,线程安全是一个核心问题。当多个线程同时访问共享资源时,可能会导致数据不一致或其他不可预期的结果。synchronized关键字和Lock接口是 Java 中实现线程同步的…...

贪心算法应用:最大匹配问题详解
Java中的贪心算法应用:最大匹配问题详解 贪心算法是一种在每一步选择中都采取当前状态下最优的选择,从而希望导致结果是全局最优的算法策略。在Java中,贪心算法可以应用于多种问题,其中最大匹配问题是一个经典的应用场景。下面我将从基础概念到具体实现,全面详细地讲解贪…...

爬虫IP代理效率优化:策略解析与实战案例
目录 一、代理池效率瓶颈的根源分析 二、六大核心优化策略 策略1:智能IP轮换矩阵 策略2:连接复用优化 策略3:动态指纹伪装 策略4:智能重试机制 三、典型场景实战案例 案例1:电商价格监控系统 案例2:…...

豆瓣电视剧数据工程实践:从爬虫到智能存储的技术演进(含完整代码)
通过网盘分享的文件:资料 链接: https://pan.baidu.com/s/1siOrGmM4n-m3jv95OCea9g?pwd4jir 提取码: 4jir 1. 引言 1.1 选题背景 在影视内容消费升级背景下,豆瓣电视剧榜单作为国内最具影响力的影视评价体系,其数据价值体现在:…...
【HW系列】—C2远控服务器(webshell链接工具, metasploit、cobaltstrike)的漏洞特征流量特征
文章目录 蚁剑、冰蝎、哥斯拉一、蚁剑(AntSword)流量特征二、冰蝎(Behinder)流量特征三、哥斯拉(Godzilla)流量特征 metasploit、cobaltstrike一、Metasploit流量特征二、CobaltStrike流量特征三、检测与防…...
5.28 孔老师 nlp讲座
本次讲座主要介绍了语言模型的起源、预训练模型以及大语言模型(需要闫老师后讲)等内容。首先,语言模型的起源可以追溯到语音识别中的统计语言模型,通过估计声学参数串产生文字串的概率来找到最大概率的文字串。然后,介…...

基于微信小程序的漫展系统的设计与实现
博主介绍:java高级开发,从事互联网行业六年,熟悉各种主流语言,精通java、python、php、爬虫、web开发,已经做了六年的毕业设计程序开发,开发过上千套毕业设计程序,没有什么华丽的语言࿰…...
打卡day39
一、 图像数据的介绍 1.1 灰度图像 # 先继续之前的代码 import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader , Dataset # DataLoader 是 PyTorch 中用于加载数据的工具 from torchvision import datasets, transforms…...

基于Web的分布式图集管理系统架构设计与实践
引言:为什么需要分布式图集管理? 在现代Web图形应用中,纹理图集(Texture Atlas)技术是优化渲染性能的关键手段。传统的图集制作流程通常需要美术人员使用专业工具(如TexturePacker)离线制作&am…...

mysql执行sql语句报错事务锁住
报错情况 1205 - Lock wait timeout exceeded; try restarting transaction先找出长时间运行的事务 SELECT * FROM information_schema.INNODB_TRX ORDER BY trx_started ASC;终止长时间运行的事务 KILL [PROCESS_ID];...

Java消息队列应用:Kafka、RabbitMQ选择与优化
Java消息队列应用:Kafka、RabbitMQ选择与优化 在Java应用领域,消息队列是实现异步通信、应用解耦、流量削峰等重要功能的关键组件。Kafka和RabbitMQ作为两种主流的消息队列技术,各有特点和适用场景。本文将深入探讨Kafka和RabbitMQ在Java中的…...

零基础设计模式——结构型模式 - 组合模式
第三部分:结构型模式 - 组合模式 (Composite Pattern) 在学习了桥接模式如何分离抽象和实现以应对多维度变化后,我们来探讨组合模式。组合模式允许你将对象组合成树形结构来表现“整体-部分”的层次结构。组合模式使得用户对单个对象和组合对象的使用具…...
额度年审领域知识讲解
金融领域的“额度年审”是一个非常重要的常规性工作。它指的是金融机构(主要是银行)对其授予客户的各种信用额度或授信额度,在授信有效期内(通常是一年)进行周期性的重新评估、审查和确认的过程。 核心目的࿱…...

腾讯云国际站可靠性测试
在数字化转型加速的今天,企业对于云服务的依赖已从“可选”变为“必需”。无论是跨境电商的实时交易,还是跨国企业的数据协同,云服务的可靠性直接决定了业务连续性。作为中国领先的云服务提供商,腾讯云国际站(Tencent …...

自定义异常小练习
在开始之前,让我们高喊我们的口号: 键盘敲烂,年薪百万! 目录 键盘敲烂,年薪百万! 异常综合练习: 自定义异常 异常综合练习: 自定义异常: 定义异常类写继承关系空参构造带参构造 自定…...

SpringBoot整合MinIO实现文件上传
使用Spring Boot与JSP和MinIO(一个开源对象存储系统,兼容Amazon S3)进行集成,您可以创建一个Web应用来上传、存储和管理文件。以下是如何将Spring Boot、JSP和MinIO集成的基本步骤: 这个是minio正确启动界面 这个是min…...

基于面向对象设计的C++日期推算引擎:精准高效的时间运算实现与运算重载工程化实践
前引: 在软件开发中,时间与日期的处理是基础但极具挑战性的任务。传统的手工日期运算逻辑往往面临闰年规则、月份天数动态变化、时区转换等复杂场景的容错难题,且代码冗余度高、可维护性差。本文将深入探讨如何利用C的面向对象特性与成员函数…...

如何把 Microsoft Word 中所有的汉字字体替换为宋体?
Ctrl H ,然后,点击更多,勾选使用通配符,查找内容中填入 [一-龥]{1,}, 这是 Word 通配符匹配汉字的经典写法(匹配 Unicode 范围内的 CJK 汉字)。 然后, “替换为”留空,点…...
02. [Python+Golang+PHP]三数之和,多种语言实现最优解demo
一、问题描述:三数之和 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k ,同时还满足 nums[i] nums[j] nums[k] 0 。请你返回所有和为 0 且不重复的三元组。 注意:答案中…...
MongoDB选择理由
1.简介 MongoDB是一个基于分布式文件存储的数据库由C语言编写,旨在为WEB应用提供可扩展的高性能数据存储解决方案。MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。Mongo最大的特点是…...