React 生命周期完整指南
React 生命周期完整指南
1. 生命周期概述
1.1 React 16.3 之前的生命周期
- 初始化阶段
- constructor
- componentWillMount
- render
- componentDidMount
- 更新阶段
- componentWillReceiveProps
- shouldComponentUpdate
- componentWillUpdate
- render
- componentDidUpdate
- 卸载阶段
- componentWillUnmount
1.2 React 16.3 之后的生命周期
- 初始化阶段
- constructor
- getDerivedStateFromProps
- render
- componentDidMount
- 更新阶段
- getDerivedStateFromProps
- shouldComponentUpdate
- render
- getSnapshotBeforeUpdate
- componentDidUpdate
- 卸载阶段
- componentWillUnmount
2. 详细说明
2.1 挂载阶段
class MyComponent extends React.Component {// 1. 构造函数constructor(props) {super(props);this.state = {count: 0};console.log('1. constructor');}// 2. 派生状态static getDerivedStateFromProps(props, state) {console.log('2. getDerivedStateFromProps');return null;}// 3. 渲染render() {console.log('3. render');return <div>{this.state.count}</div>;}// 4. 挂载完成componentDidMount() {console.log('4. componentDidMount');}
}
2.2 更新阶段
class UpdateComponent extends React.Component {// 1. 派生状态static getDerivedStateFromProps(props, state) {console.log('1. getDerivedStateFromProps');return null;}// 2. 是否应该更新shouldComponentUpdate(nextProps, nextState) {console.log('2. shouldComponentUpdate');return true;}// 3. 渲染render() {console.log('3. render');return <div>{this.state.count}</div>;}// 4. 获取更新前的快照getSnapshotBeforeUpdate(prevProps, prevState) {console.log('4. getSnapshotBeforeUpdate');return null;}// 5. 更新完成componentDidUpdate(prevProps, prevState, snapshot) {console.log('5. componentDidUpdate');}
}
2.3 卸载阶段
class UnmountComponent extends React.Component {componentWillUnmount() {console.log('componentWillUnmount');// 清理工作:取消订阅、清除定时器等}
}
3. 新旧生命周期对比
3.1 被移除的生命周期方法
componentWillMount
// 旧版本
componentWillMount() {// 组件即将挂载// 问题:可能会导致服务器端渲染问题
}// 新版本替代方案
componentDidMount() {// 组件已挂载// 建议在这里进行异步操作
}
componentWillReceiveProps
// 旧版本
componentWillReceiveProps(nextProps) {// 即将接收新的 propsif (nextProps.value !== this.props.value) {this.setState({ value: nextProps.value });}
}// 新版本替代方案
static getDerivedStateFromProps(props, state) {if (props.value !== state.value) {return { value: props.value };}return null;
}
componentWillUpdate
// 旧版本
componentWillUpdate(nextProps, nextState) {// 即将更新// 问题:可能会导致异步渲染问题
}// 新版本替代方案
getSnapshotBeforeUpdate(prevProps, prevState) {// 获取更新前的快照return null;
}
3.2 新增的生命周期方法
getDerivedStateFromProps
class Example extends React.Component {static getDerivedStateFromProps(props, state) {// 返回新状态或 nullif (props.currentRow !== state.lastRow) {return {isScrollingDown: props.currentRow > state.lastRow,lastRow: props.currentRow};}return null;}
}
getSnapshotBeforeUpdate
class ScrollingList extends React.Component {getSnapshotBeforeUpdate(prevProps, prevState) {// 捕获更新前的信息if (prevProps.list.length < this.props.list.length) {const list = this.listRef.current;return list.scrollHeight - list.scrollTop;}return null;}componentDidUpdate(prevProps, prevState, snapshot) {// 使用快照信息if (snapshot !== null) {const list = this.listRef.current;list.scrollTop = list.scrollHeight - snapshot;}}
}
4. 生命周期最佳实践
4.1 常见用途
class BestPractices extends React.Component {constructor(props) {super(props);// 初始化状态// 绑定方法}static getDerivedStateFromProps(props, state) {// 用于状态的派生// 不要在这里执行副作用return null;}componentDidMount() {// 适合执行副作用// - 网络请求// - DOM 操作// - 订阅}shouldComponentUpdate(nextProps, nextState) {// 性能优化// 返回 false 可以阻止更新return true;}getSnapshotBeforeUpdate(prevProps, prevState) {// 获取 DOM 更新前的信息return null;}componentDidUpdate(prevProps, prevState, snapshot) {// 更新后的操作// 可以执行副作用// 注意避免无限循环}componentWillUnmount() {// 清理工作// - 取消订阅// - 清除定时器// - 取消网络请求}
}
4.2 错误处理
class ErrorBoundary extends React.Component {state = { hasError: false };static getDerivedStateFromError(error) {// 更新状态,下次渲染时显示降级 UIreturn { hasError: true };}componentDidCatch(error, errorInfo) {// 记录错误信息console.error('Error:', error);console.error('Error Info:', errorInfo);}render() {if (this.state.hasError) {return <h1>Something went wrong.</h1>;}return this.props.children;}
}
5. Hooks 时代的生命周期
5.1 使用 Hooks 模拟生命周期
function HooksLifecycle() {// 模拟 constructorconst [state, setState] = useState({count: 0});// 模拟 componentDidMountuseEffect(() => {console.log('Component mounted');return () => {// 模拟 componentWillUnmountconsole.log('Component will unmount');};}, []);// 模拟 componentDidUpdateuseEffect(() => {console.log('State updated:', state);}, [state]);return <div>{state.count}</div>;
}
5.2 生命周期方法与 Hooks 对照表
| 生命周期方法 | Hooks 实现 |
|---|---|
| constructor | useState |
| componentDidMount | useEffect(() => {}, []) |
| componentDidUpdate | useEffect(() => {}, [deps]) |
| componentWillUnmount | useEffect(() => { return () => {} }, []) |
| shouldComponentUpdate | useMemo, useCallback |
| getDerivedStateFromProps | useState + useEffect |
6. 总结
6.1 生命周期选择建议
- 使用
componentDidMount进行初始化操作 - 使用
componentDidUpdate响应更新 - 使用
componentWillUnmount清理资源 - 优先考虑新的生命周期方法
- 在合适的场景使用 Hooks
6.2 注意事项
- 避免在构造函数中执行副作用
- 不要在
getDerivedStateFromProps中执行副作用 - 谨慎使用
shouldComponentUpdate - 在
componentDidUpdate中注意避免无限循环 - 确保在
componentWillUnmount中清理所有副作用
6.3函数组件中的生命周期(通过 Hooks)
useEffect 可以模拟 componentDidMount 和 componentDidUpdate,通过将依赖项传递给 useEffect 来控制副作用的执行。传递空数组 [] 作为依赖项时,useEffect 只会在组件首次挂载时执行,相当于 componentDidMount。
清理副作用:useEffect 可以返回一个清理函数,相当于类组件中的 componentWillUnmount。
import React, { useState, useEffect } from 'react';const MyFunctionComponent = () => {const [counter, setCounter] = useState(0);// 模拟 componentDidMount 和 componentDidUpdateuseEffect(() => {console.log('组件已挂载或更新');// 模拟 componentWillUnmountreturn () => {console.log('组件将卸载');};}, [counter]); // 依赖项,只有当 counter 更新时,才会重新执行 useEffectreturn (<div><p>Counter: {counter}</p><button onClick={() => setCounter(counter + 1)}>增加计数</button></div>);
};export default MyFunctionComponent;
6.4 React 18 的新特性
React 18 引入了多个新特性,最显著的之一是 并发模式(Concurrent Mode),它改善了渲染性能,尤其是在 React 应用的响应式方面。虽然并发模式与生命周期方法的直接关系不大,但它会影响组件的挂载、更新和卸载过程。
React 18 还引入了 自动批量更新(Automatic Batching)和 Suspense 进一步增强了异步渲染的能力。这些新特性和生命周期方法并没有冲突,而是增强了现有的机制。
总结:
类组件:React 18 中,类组件的生命周期方法仍然有效,且与之前的版本一样。
函数组件:函数组件使用 useEffect 和其他 Hooks 来模拟传统的生命周期方法。
React 18 新特性:引入了并发模式、自动批量更新等,但它不会影响生命周期方法。
因此,如果你使用类组件,React 18 中依然可以使用传统的生命周期方法。如果使用函数组件,你可以通过 useEffect 来替代和模拟传统生命周期的行为。
相关文章:
React 生命周期完整指南
React 生命周期完整指南 1. 生命周期概述 1.1 React 16.3 之前的生命周期 初始化阶段 constructorcomponentWillMountrendercomponentDidMount 更新阶段 componentWillReceivePropsshouldComponentUpdatecomponentWillUpdaterendercomponentDidUpdate 卸载阶段 componentWil…...
python中os._exit(0) 强制关闭进程后来杀死线程
在 Python 中调用 os._exit(0) 会强制终止整个进程,包括所有正在运行的线程。以下是详细解释: os._exit(0) 的行为 立即终止进程:os._exit() 函数会立即终止当前进程,不会执行任何清理操作,如调用清理处理程序&#…...
LeetCode:257. 二叉树的所有路径
跟着carl学算法,本系列博客仅做个人记录,建议大家都去看carl本人的博客,写的真的很好的! 代码随想录 LeetCode:257. 二叉树的所有路径 给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根…...
RSICV国产芯片之CHV208
1. 芯片选型分析的对比维度 分析或者对标应用的芯片替代思路 1.1 内核/主频/存储空间支持 内核能力/指令集支持(考虑工具链兼容性); 主频:对比计算能力是否满足基本要求 存储:内存--数据搬移空间决定数据运算的…...
理解神经网络
神经网络是一种模拟人类大脑工作方式的计算模型,是深度学习和机器学习领域的基础。 基本原理 神经网络的基本原理是模拟人脑神经系统的功能,通过多个节点(也叫神经元)的连接和计算,实现非线性模型的组合和输出。每个…...
Android 之 List 简述
一、简单创建方式 Android 开发中,列表有很多种类,如ArrayList、LinkedList、List、MutableList等,创建列表的方式如下所示: fun listDemo() {// 使用 listOf 创建不可变的空列表val list listOf<Int>()val list1 listOf…...
设计模式の中介者发布订阅备忘录模式
文章目录 前言一、中介者模式二、发布订阅模式三、备忘录模式 前言 本篇是关于设计模式中介者模式、观察者(发布-订阅)模式、以及备忘录模式的学习笔记。 一、中介者模式 中介者模式是一种行为型设计模式,其核心目的是为了减少对象之间的复杂…...
云手机群控能用来做什么?
随着云手机的发展,云手机群控技术逐渐从小众的游戏多开工具,发展为涵盖多个领域的智能操作平台。不论是手游搬砖、短视频运营,还是账号养成等场景,云手机群控都展现出了强大的应用潜力。本文将为大家详细解析云手机群控的应用场景…...
fpgafor循环语句使用
genvar i;//循环变量名称 generate for(i0;i<4;ii1)begin:tx//自己定义名称 //循环内容 end endgenerate12位的16进制乘以4就是48位位宽的2进制 因为 222*2(2^4)16...
【FastAPI】BaseHTTPMiddleware类
一、概述 在FastAPI中,BaseHTTPMiddleware 类是Starlette框架提供的一个抽象基类,它允许开发者基于HTTP请求/响应接口编写ASGI中间件。 这个类对于希望实现自定义中间件逻辑的开发者来说是非常重要的工具。 通过继承 BaseHTTPMiddleware 并实现特定的方…...
Solon v3.0.5 发布!(Spring 可以退休了吗?)
Solon 框架! 新一代,面向全场景的 Java 应用开发框架。从零开始构建(非 java-ee 架构),有灵活的接口规范与开放生态。 追求: 更快、更小、更简单提倡: 克制、高效、开放、生态 有什么特点&am…...
网络安全攻防演练中的常见计策
大家觉得有意义记得关注和点赞!!! 引言 在网络安全攻防演练里面,用于分析攻击者动机和行为的,国外的有基于攻击链分析的模型(如Cyber Kill Chain和ATT&CK)和基于威胁行为的模型(…...
SD卡模块布局布线设计
1、SD/TF/SIM卡的定义 2、SD/TF/SIM卡模块引脚定义以及图示 3、SD/TF/SIM卡接口布局和布线 4、小结 1、BGA两线交叉时,可以在源头将两线互相短路连接,然后再输出口删除一小节线,然后CHRLX/V,这样就可以换两条线的网络,…...
Flask-----SQLAlchemy教程
存session session[username] username # 存储数据到 session 取session username session.get(username) render_template return render_template(index.html, usernameAlice),渲染一个包含 username 变量的模板。 redirect return redirect(url_for(profil…...
STM32 高级 物联网通信之CAN通讯
目录 CAN通讯介绍 物理层 协议层 CAN的帧(报文)种类 1 数据帧(发送单元->接受单元) 2 远程帧(接受单元->发送单元) 3 错误帧(发送方发送数据错误会发送的状态帧) 4 过载帧(接收方放不下会发送到的状态帧) 5 帧间隔(状态) 数据帧介绍 远程帧介绍 C…...
“乡村探索者”:村旅游网站的移动应用开发
3.1 可行性分析 从三个不同的角度来分析,确保开发成功的前提是有可行性分析,只有进行提前分析,符合程序开发流程才不至于开发过程的中断。 3.1.1 技术可行性 在技术实现层次,分析了好几种技术实现方法,并且都有对应的成…...
前端案例---自定义鼠标右键菜单
之前右击出现默认的选项菜单,使用evt.preventDefault()把默认的去掉,然后自定义右击的样式 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible"…...
浅谈归一化
在深度学习中,对网络层进行归一化(Normalization,简称Norm)是一个重要的技巧。常见的归一化方法包括批归一化(Batch Normalization)、层归一化(Layer Normalization)、实例归一化&am…...
lodash常用函数
文章目录 一、数组1、chunk分组2、difference、differenceBy、differenceWith3、findIndex4、intersection、intersectionBy、intersectionWith5、union、unionBy、unionWith 二、对象1、pick、omit 2、get、set三、数学1、sum、sumBy2、range 四、工具函数1、isEqual、isEmpty…...
触控算法总结
一、触控湿手指算法的具体实现原理涉及多个方面的技术和方法,主要包括以下几个关键点 1.电容变化检测 电容式触摸屏通过检测电容变化来确定触摸位置。当手指接触屏幕时,会引起电容的变化。然而,当手指湿润时,水分会影响电容值,导致触摸屏误判成无法正确识别触控点 2.噪声过滤: …...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
关于uniapp展示PDF的解决方案
在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项: 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库: npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...
Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)
引言 工欲善其事,必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后,我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集,就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...
Python学习(8) ----- Python的类与对象
Python 中的类(Class)与对象(Object)是面向对象编程(OOP)的核心。我们可以通过“类是模板,对象是实例”来理解它们的关系。 🧱 一句话理解: 类就像“图纸”,对…...
归并排序:分治思想的高效排序
目录 基本原理 流程图解 实现方法 递归实现 非递归实现 演示过程 时间复杂度 基本原理 归并排序(Merge Sort)是一种基于分治思想的排序算法,由约翰冯诺伊曼在1945年提出。其核心思想包括: 分割(Divide):将待排序数组递归地分成两个子…...
boost::filesystem::path文件路径使用详解和示例
boost::filesystem::path 是 Boost 库中用于跨平台操作文件路径的类,封装了路径的拼接、分割、提取、判断等常用功能。下面是对它的使用详解,包括常用接口与完整示例。 1. 引入头文件与命名空间 #include <boost/filesystem.hpp> namespace fs b…...
