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.噪声过滤: …...
比迪丽SDXL模型GPU算力适配:A10/A100/V100/T4多卡实测报告
比迪丽SDXL模型GPU算力适配:A10/A100/V100/T4多卡实测报告 1. 引言 如果你玩过AI绘画,肯定遇到过这样的问题:同一个模型,为什么在别人的电脑上跑得飞快,在自己这儿却慢如蜗牛?生成一张图要等好几分钟&…...
OpenClaw+Phi-3-vision-128k-instruct内容创作流:从图文素材到Markdown自动排版
OpenClawPhi-3-vision-128k-instruct内容创作流:从图文素材到Markdown自动排版 1. 为什么需要自动化内容创作流 作为一个长期与图文内容打交道的创作者,我每天都要处理大量零散的素材——截图、手写笔记、PPT片段、网页摘录。最痛苦的不是创作本身&…...
GDScriptDecomp源码编译指南:从零构建自定义逆向工程工具
GDScriptDecomp源码编译指南:从零构建自定义逆向工程工具 【免费下载链接】gdsdecomp Godot reverse engineering tools 项目地址: https://gitcode.com/GitHub_Trending/gd/gdsdecomp GDScriptDecomp是一款强大的Godot逆向工程工具,它能够帮助开…...
不止是安装:在openEuler 22.03 LTS SP4上快速搭一个可用的开发/测试环境
从裸机到生产力:openEuler 22.03 LTS SP4半小时高效开发环境搭建指南 刚装完openEuler系统,看着空荡荡的终端界面,是不是有种"接下来该干嘛"的迷茫?作为开发者,我们需要的不是一个干净的操作系统,…...
【AI】Datadog
Datadog是当前全球范围内最主流的商业可观测性平台,是一个将监控、安全与AI分析深度整合的SaaS服务。 作为业界公认的领军者,其核心价值在于提供了一个 “大一统”的中央控制台,帮助企业技术团队全面洞察其整个技术栈的运行状况。在AI快速发展…...
C++20 中的协程与异步 I/O:探索高效编程新路径
C20 中的协程与异步 I/O:探索高效编程新路径 在 C 的发展历程中,每一次标准的更新都为开发者带来了新的特性和工具,以提升代码的性能、可读性和开发效率。C20 作为一次重要的更新,引入了协程这一强大的特性,它与异步 I…...
Golang GORM怎么做Scopes复用_Golang GORM Scopes教程【推荐】
Scopes 是接收并返回 *gorm.DB 的函数,用于链式构建查询;需严格签名、避免提前执行、显式传参、控制分页参数、顺序影响SQL逻辑、事务中注意句柄、不处理错误。Scopes 就是带参数的 func(*gorm.DB) *gorm.DB它不是魔法,就是个普通函数签名——…...
simulink和carsim联合仿真的mpc轨迹跟踪模型。
simulink和carsim联合仿真的mpc轨迹跟踪模型。MPC(模型预测控制)轨迹跟踪模型在Simulink和Carsim联合仿真中,通过构建车辆动力学模型、设计MPC控制器,实现对车辆轨迹的精准跟踪。其代码涉及车辆状态方程、MPC优化算法等核心部分。…...
Windows 11 LTSC系统快速安装微软商店:3分钟完成完整解决方案
Windows 11 LTSC系统快速安装微软商店:3分钟完成完整解决方案 【免费下载链接】LTSC-Add-MicrosoftStore Add Windows Store to Windows 11 24H2 LTSC 项目地址: https://gitcode.com/gh_mirrors/ltscad/LTSC-Add-MicrosoftStore Windows 11 LTSC版本以其卓越…...
5分钟为Windows 11 24H2 LTSC恢复微软应用商店:小白也能懂的完整教程
5分钟为Windows 11 24H2 LTSC恢复微软应用商店:小白也能懂的完整教程 【免费下载链接】LTSC-Add-MicrosoftStore Add Windows Store to Windows 11 24H2 LTSC 项目地址: https://gitcode.com/gh_mirrors/ltscad/LTSC-Add-MicrosoftStore 还在为Windows 11 24…...
