react生命周期详解,代码示例(新生命周期,与旧生命周期对比)

旧生命周期:https://blog.csdn.net/kkkys_kkk/article/details/135130549?spm=1001.2014.3001.5501

目录

React 生命周期中常见的坑

为什么要移除 “will” 相关生命周期方法呢?

Fiber是什么 

新生命周期图示

新增生命周期与功能变化

完整生命周期

新增三个生命周期详解

static getDerivedStateFromProps(props, state)

getSnapshotBeforeUpdate(prevProps, prevState)

 componentDidCatch(error, info)


 

React 生命周期中常见的坑

在 React 生命周期中,确实有一些常见的坑特别是在使用旧版的生命周期方法时可能会遇到一些问题。以下是一些常见的 React 生命周期中的坑:

  1. 引起性能问题:在较大的应用程序中,频繁地使用生命周期方法可能会导致性能问题,特别是在应用没有正确地处理数据更新和组件挂载/卸载时。

  2. 编写复杂的逻辑:有时候在生命周期方法中编写复杂的逻辑可能会导致代码难以维护和理解。

  3. 容易出错:对于初学者来说,理解和正确使用生命周期方法可能会存在一些困难,容易出现错误。

为什么要移除 “will” 相关生命周期方法呢?

在 React 16 版本之后,React 推出了异步渲染机制,也就是 Fiber。Fiber 的目标是实现增量渲染,以提高应用的性能和响应性。为了实现这一目标,React 对生命周期函数进行了重构和调整。

在过去的版本中,生命周期函数的执行顺序是固定的,也就是按照 Mounting 阶段(挂载)、Updating 阶段(更新)、Unmounting 阶段(卸载)的顺序执行。而在 Fiber 中,React 引入了任务优先级和工作单元的概念,使得组件的更新可以被打断和中断,并且可以根据任务的优先级进行调度。

为了更好地适应 Fiber 架构的变化,React 做出了一些生命周期函数的修改。其中,将 "Will" 阶段的生命周期函数改为以 "Did" 开头,表示在对应阶段的结束时调用,也就是在 DOM 更新之后调用,比如 componentDidMount 和 componentDidUpdate。这样做的目的是为了避免阻塞渲染和影响性能,因为在某些情况下,组件的更新可能会被打断或延迟执行。

主要的原因有以下几点:

  1. 性能优化:这些旧生命周期方法在某些情况下可能会引起意外的副作用,对于 React 内部的优化和异步更新可能存在一些问题。

  2. 统一更新流程:使用异步的方式来处理生命周期方法和更新流程,能够使得 React 的更新机制更加一致和可预测。

  3. 更好的开发体验:通过移除一些多余的生命周期方法,能够让开发者更加专注于核心逻辑的编写,减少一些复杂性和潜在的错误。

Fiber是什么 

Fiber 是 React 16 引入的一种新的协调机制,用于实现可中断和增量渲染,以提高 React 应用程序的性能和用户体验。

在 React 15 及以前的版本中,React 使用递归调用来处理组件的协调和渲染。这种方法在组件层级很深或组件树很大时,可能会导致阻塞主线程,影响用户交互和动画的流畅性。另外,由于整个协调过程是同步的,每个组件都会被完整地协调和渲染,无论它们是否发生了实际的变化,这也会影响到应用程序的性能。

Fiber 的引入解决了这些问题。它将协调过程分为多个小的单元(fiber),并使用优先级调度算法来决定哪些任务需要优先处理,以便在每个帧(frame)中均匀地分配工作量,并且能够根据主线程的空闲时间暂停、恢复和中断渲染。这样就可以实现可中断的渲染,使得 React 应用程序更加响应,减少阻塞,提高用户体验。

Fiber 架构的核心思想是将协调过程划分为多个优先级不同、可中断的任务,并使用双缓冲技术进行渲染。当浏览器有空闲时间时,React 会从高优先级任务开始,逐步执行协调和渲染工作,同时在每个步骤之间检查是否还有剩余的时间。如果时间快要用完了,React 将暂停当前任务,将控制权交还给浏览器,等下一次浏览器空闲时再继续工作。这样就能够实现平滑、可中断的渲染过程,避免阻塞主线程,保证用户交互的响应性。

通过 Fiber,React 还引入了一些新的特性和能力,例如异步渲染、并发模式、错误边界等,进一步提升了 React 应用程序的性能和可维护性。

总之,Fiber 是 React 的一种新的协调机制,用于实现可中断和增量渲染,提高应用程序的性能和用户体验。它将协调过程分解为多个小任务,并使用优先级调度算法,实现了平滑、可中断的渲染。

新生命周期图示

新增生命周期与功能变化

在 React v16.3 之后,引入了新的生命周期方法,并对原有的生命周期方法进行了改动。

以下是 React 中新增的生命周期方法:

1. static getDerivedStateFromProps(props, state):这个生命周期方法在组件实例化之后和每次接收新的 props 之前被调用,用于根据新的 props 来更新组件的状态。它应该返回一个对象,用于更新组件的状态,或者返回 null 表示不需要更新状态。

2. getSnapshotBeforeUpdate(prevProps, prevState):这个生命周期方法在组件即将更新之前被调用,它的返回值将作为 componentDidUpdate 方法的第三个参数。通常在这个方法中可以获取组件更新前的某些 DOM 信息,并在组件更新后进行相应的操作。

3. componentDidCatch(error, info):这个生命周期方法在子组件抛出错误时被调用,用于捕获并处理组件渲染过程中的错误。它接收两个参数,分别是错误对象和包含组件堆栈信息的对象。使用 componentDidCatch 可以在出错时显示错误信息,并采取适当的措施进行处理。

此外,React 还对一些原有的生命周期方法进行了改动:

1. componentWillReceiveProps(nextProps):这个生命周期方法已经被标记为过时,并在未来的版本中将会被删除。取而代之的是 `static getDerivedStateFromProps` 方法。

2. componentWillMount() 和 componentWillUpdate():这两个生命周期方法也被标记为过时,并在未来的版本中将会被删除。相应的替代方法是 `componentDidMount` 和 `componentDidUpdate`。

需要注意的是,在使用新的生命周期方法时,我们需要谨慎处理它们的逻辑和调用时机,确保正确地使用这些生命周期方法,并避免不必要的更新和性能问题。

完整生命周期

在 React 中,组件的生命周期可以分为三个阶段:挂载、更新和卸载。每个阶段都有相应的生命周期方法可以被调用。

以下是 React 中常见的生命周期方法:

1. 挂载阶段(Mounting Phase):
   - constructor(props):构造函数,在组件被创建时调用。通常用于初始化组件的状态和绑定事件处理函数。
   - static getDerivedStateFromProps(props, state):在组件实例化之后和每次接收新的 props 之前被调用。用于根据新的 props 来更新组件的状态。
   - render():渲染方法,在挂载阶段和后续的更新阶段都会被调用。该方法负责返回组件的 JSX 结构。
   - componentDidMount():在组件挂载到 DOM 后立即调用。通常用于执行异步操作、获取数据和订阅事件。
   
2. 更新阶段(Updating Phase):
   - static getDerivedStateFromProps(props, state):同样在更新阶段也可以使用该生命周期方法来根据新的 props 更新组件的状态。
   - shouldComponentUpdate(nextProps, nextState):在组件更新之前被调用,用于决定是否要进行组件的重渲染。默认情况下,React 会自动执行浅层比较来判断是否更新组件,但你也可以通过该方法进行自定义的优化逻辑。
   - render():同挂载阶段中的 render 方法,用于渲染组件的 JSX 结构。
   - componentDidUpdate(prevProps, prevState):在组件更新后被调用。通常用于执行 DOM 操作、发起网络请求和更新其他组件的状态。
   
3. 卸载阶段(Unmounting Phase):
   - componentWillUnmount():在组件被销毁之前调用。通常用于清理组件所占用的资源、取消订阅和定时器等。

此外,还有一些其他的生命周期方法:
- static getDerivedStateFromError(error):在渲染阶段发生错误时被调用,用于根据错误而更新组件的状态。
- componentDidCatch(error, info):在渲染阶段发生错误时被调用,通常用于记录错误信息和展示错误界面。

需要注意的是,在 React 17 版本中,一些生命周期方法已经被废弃或移除。详细的信息可以参考 React 官方文档来了解最新的生命周期方法。

新增三个生命周期详解

static getDerivedStateFromProps(props, state)
getDerivedStateFromProps 属于静态方法,因此不能在该方法中访问组件实例
执行时机:组件创建时、组件更新时
执行顺序:该方法在 render 方法之前执行
接收两个参数: props 和  state。在每次组件实例化或接收到新的props时,React会调用这个方法。它应该返回一个对象来更新组件的state,或者返回  null 来表示不需要更新state。
import React from 'react';class MyComponent extends React.Component {constructor(props) {super(props);this.state = {count: 0,prevPropsValue: null,};}static getDerivedStateFromProps(props, state) {if (props.value !== state.prevPropsValue) {return {count: props.value * 2,prevPropsValue: props.value,};}return null;}render() {return (<div><p>Count: {this.state.count}</p></div>);}
}export default MyComponent;
getSnapshotBeforeUpdate(prevProps, prevState)

O 什么时候调用?
getSnapshotBeforeUpdate() 在最近一次染输出 (提交到 DOM 节点) 之前调用
O 返回值
应返回 snapshot 的值 (或null)
O有什么用途?
它使得组件能在发生更改之前从 DOM 中捕获一些信息 (例如,滚动位置)。此生命周期的任何返回值将作为参数传递给 componentDidUpdate()。
此用法并不常见,但它可能出现在 UI 处理中,如需要以特殊方式处理滚动位置的聊天线程等

import React from 'react';class MyComponent extends React.Component {constructor(props) {super(props);this.state = { messages: [] };this.myRef = React.createRef();}componentDidMount() {this.timerID = setInterval(() => {this.setState(({ messages }) => ({messages: [...messages, `Message ${messages.length + 1}`],}));}, 1000);}componentWillUnmount() {clearInterval(this.timerID);}getSnapshotBeforeUpdate(prevProps, prevState) {if (prevProps.threshold !== this.props.threshold) {const node = this.myRef.current;return node.scrollHeight - node.scrollTop;}return null;}componentDidUpdate(prevProps, prevState, snapshot) {if (snapshot !== null) {const node = this.myRef.current;node.scrollTop = node.scrollHeight - snapshot;}}render() {const { threshold } = this.props;const { messages } = this.state;return (<divref={this.myRef}style={{height: 200,width: 300,overflow: 'auto',border: '1px solid #ccc',padding: 5,margin: '0 auto',}}>{messages.map((message, index) => {return <div key={index}>{message}</div>;})}</div>);}
}export default MyComponent;
 componentDidCatch(error, info)

使用 componentDidCatch 可以捕获在组件生命周期内发生的 JavaScript 错误,包括子组件和组件树的渲染过程中发生的错误。如果你在组件中实现了 componentDidCatch 方法,那么就可以避免在应用程序中因为某个组件发生错误而导致整个应用程序崩溃。

componentDidCatch 接收两个参数:error 和 info,分别代表错误对象和包含组件堆栈信息的对象。可以在该方法中记录错误信息、发送日志或者展示错误界面。

import React, { Component } from 'react';class ErrorBoundary extends Component {state = { hasError: false, error: null, errorInfo: null };componentDidCatch(error, errorInfo) {// 将错误信息记录到 state 中,或者发送到后台进行分析this.setState({ hasError: true, error, errorInfo });}render() {const { hasError, errorInfo } = this.state;if (hasError) {// 在发生错误时展示自定义的错误界面return (<div><h2>Something went wrong.</h2><details style={{ whiteSpace: 'pre-wrap' }}>{error && error.toString()}<br />{errorInfo.componentStack}</details></div>);}// 如果没有发生错误,则正常渲染子组件return this.props.children;}
}export default ErrorBoundary;

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

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

相关文章

C语言操作符详解+运算符优先级表格

目录 前言 一、操作符是什么&#xff1f; 二、操作符的分类 三、算术操作符 四、逻辑操作符 五、比较操作符 六、位操作符 七、赋值操作符 八、其他操作符 九、运算符优先级表格 总结 前言 在编写程序时&#xff0c;最常用到的就是操作符&#xff0c;本文将详细的介绍…

Golang 的内存管理

文章目录 1.内存管理角色1.常见的内存分配方法线性分配器空闲链表分配器TCMalloc 2.Go 内存管理组件mspanmcache初始化替换微分配器 mcentralmheap 3.内存分配4.内存管理思想参考文献 1.内存管理角色 内存管理一般包含三个不同的组件&#xff0c;分别是用户程序&#xff08;Mu…

【C语言】指针详解(三)

1.指针运算 指针的基本运算有三种&#xff0c;分别是:⭐指针-整数 ⭐指针-指针 ⭐指针的关系运算 1.1指针 - 整数 因为数组在内存中是连续存放的&#xff0c;只要知道第一个元素的地址&#xff0c;顺藤摸瓜就能找到后面的所有元素。 int arr[10]{1,2,3,4,5,6,7,8,9,10} #inc…

劈窗算法反演地表温度

目录 摘要操作步骤提取热红外单波段提取NDVI同步像元分辨率与个数劈窗算法地表温度反演制图 摘要 主要使用HJ-2&#xff08;环境减灾二号卫星&#xff09;的IRS传感器的两个热红外波段&#xff0c;以及红波段与近红波段计算得到的NDVI&#xff0c;使用劈窗算法&#xff0c;得到…

贪吃蛇(五)蛇撞墙

上节我们实现了蛇身向右移动的功能&#xff0c;原理就是增加一个节点&#xff0c;删除一个节点。 本节我们处理蛇撞墙重置的功能 实现原理 在移动函数中检查蛇头&#xff08;链表尾节点&#xff09;是否达到墙边的坐标&#xff0c;这里有四种撞墙的情况&#xff1a; 上墙&am…

使用Docker-镜像命令

镜像名称一般分两部分组成:[repository]:[tag] 在没有指定tag时&#xff0c;默认是latest&#xff0c;代表最新版本的镜像 案例一&#xff1a;从DockerHub中拉取一个nginx镜像并查看 1.1. 首先去镜像仓库搜索nginx镜像&#xff0c;比如DockerHub 点击nginx 复制拉取命令 1.2.…

MySQL中替换字符串中的指定部分之REPLACE函数

REPLACE函数是用来替换字符串中的指定部分内容的。在本文中&#xff0c;将介绍如何在MySQL中使用REPLACE函数进行字符串替换 REPLACE函数的语法&#xff1a; REPLACE(str, search_str, replace_str) 其中&#xff0c;str是要进行替换操作的字符串&#xff0c;search_str是要搜…

使用Mosquitto/python3进行MQTT连接

一、简介 MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于发布/订阅范式的消息协议。它工作在 TCP/IP协议族上&#xff0c;是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议&#xff0c;为此&#xff0c;它需要一个消息中间件。 …

【CMake保姆级教程】制作动静态链接库、指定动静态库输出路径

文章目录 前言一、动静态链接库的介绍1.1 动态链接库 (DLL)1.2 静态链接库 (LIB) 二、制作静态库三、制作动态库四、指定动静态库输出路径4.1 方式1 - 适用于动态库4.2 方式2 - 都适用 总结 前言 在软件开发中&#xff0c;我们经常听到动态链接库&#xff08;Dynamic Link Lib…

[LitCTF 2023]PHP是世界上最好的语言!!

[LitCTF 2023]PHP是世界上最好的语言&#xff01;&#xff01; wp 进入页面&#xff0c;发现左边有输入框&#xff0c;下面有 RUN CODE 字样&#xff0c;估计是可以执行命令的。 执行 PHP 代码测试 <?php print(1); ?>将 PHP 一句话木马写入文件 为了蚁剑能连上&am…

全国30米分辨率逐年最大NDVI数据集

全国30米分辨率逐年最大NDVI数据集 中国30m逐年NDVI最大值数据集是基于Google Earth Engine&#xff08;GEE&#xff09;遥感云计算平台&#xff0c;利用美国陆地卫星Landsat 5/7/8/9遥感影像计算的1986年以来的逐年度NDVI最大值数据集。计算过程中对每年度全年所有的Landsat5/…

智能算力进阶C位,揭秘人工智能产业背后的“冰山一角”

作者 | 曾响铃 文 | 响铃说 前几年&#xff0c;在IDC领域&#xff0c;市场谈及最多的还是数据中心&#xff0c;随着人工智能产业的成熟&#xff0c;特别是今年以来大模型的爆发&#xff0c;智算中心逐步替代了数据中心进入大众视野&#xff0c;成为市场热议的关键词&#xff…

hbase用shell命令新建表报错ERROR: KeeperErrorCode = NoNode for /hbase/master

或者HMster开启后几秒消失问题解决 报错如图&#xff1a; 首先jps命令查看当前运行的内容有没有HMaster,如果没有&#xff0c;开启一下hbase,稍微等一会儿&#xff0c;再看一下HMaster,如果仍和下图一样没有&#xff0c;就基本找到问题了 本人问题原因&#xff1a;hbase-site…

redis 从0到1完整学习 (四):字符串 SDS 数据结构

文章目录 1. 引言2. redis 源码下载3. 字符串数据结构4. 参考 1. 引言 前情提要&#xff1a; 《redis 从0到1完整学习 &#xff08;一&#xff09;&#xff1a;安装&初识 redis》 《redis 从0到1完整学习 &#xff08;二&#xff09;&#xff1a;redis 常用命令》 《redis…

【每日一题】美丽塔 II

Tag 【单调栈】【数组】【2023-12-21】 题目来源 2866. 美丽塔 II 题目解读 题目意思相对明确&#xff0c;所谓的美丽塔数组就是山状数组&#xff0c;即有一个高度为 maxHeight[i] 的山峰&#xff0c;山峰两侧的高度要小于 maxHeight[i] 并且小于各自的允许高度。需要找出满…

Simulink仿真中Sine Wave产生的正弦波形不规则,怎么解决

在使用simulink仿真时&#xff0c;使用Sine Wave模块产生的正弦波形不是正弦的&#xff0c;如下所示&#xff1a; 这个是由于simulink仿真中自动计算步长很长的原因导致的&#xff0c;此时需要将自动的步长更改&#xff0c;操作步骤如下所示&#xff1a; 1.点击设置按钮&#…

Unresolved plugin: ‘org.apache.maven.plugins‘解决报错

新建springboot项目报Unresolved plugin: ‘org.apache.maven.plugins:maven-surefire-plugin:3.1.2’ 缺什么插件 引入什么插件的依赖就行 <dependency><groupId>org.apache.maven.plugins</groupId><artifactId>maven-install-plugin</artifact…

如何使用 Helm 在 K8s 上集成 Prometheus 和 Grafana|Part 1

本系列将分成三个部分&#xff0c;您将学习如何使用 Helm 在 Kubernetes 上集成 Prometheus 和 Grafana&#xff0c;以及如何在 Grafana 上创建一个简单的控制面板。Prometheus 和 Grafana 是 Kubernetes 最受欢迎的两种开源监控工具。学习如何使用 Helm 集成这两个工具&#x…

STM32的以太网外设+PHY(LAN8720)使用详解(6):以太网数据接收及发送

0 工具准备 1.野火 stm32f407霸天虎开发板 2.LAN8720数据手册 3.STM32F4xx中文参考手册1 以太网数据接收及发送 1.1 以太网数据接收&#xff08;轮询&#xff09; 1.1.1 检查是否接收到一帧完整报文 使用轮询的方式接收以太网数据是一种简单但是效率低下的方法&#xff0c;…

2023 下半年系统架构设计师学习进度

文章目录 复习计划&#xff1a;每周350分钟第一周&#xff08;339分钟&#xff09;第二周&#xff08;265分钟&#xff09;第三周&#xff08;171分钟&#xff09;第四周&#xff08;214分钟&#xff09;第五周&#xff08;274分钟&#xff09;第六周&#xff08;191分钟&#…