React原理 - React New Component Lifecycle

目录

扩展学习资料

React New Component Lifecycle【新生命周期】

React 组件新生命周期详解

React组件老生命周期 v15.x

为什么Fiber Reconciler要有新的生命周期函数呢?

新的组件生命周期

getDerivedStateFromProps

挂载阶段

更新阶段

卸载阶段

异常捕获

新版组件升级

升级组件版本

APP.js

component.js

升级组件遍布-保留选项


扩展学习资料

名称

链接

React 组件

React.Component – React

React v16.3 组件生命周期

关于React v16.3 新生命周期 - 掘金

React 组件图

React lifecycle methods diagram

React New Component Lifecycle【新生命周期】

掌握新的组件生命周期,在老的生命周期组件中进行更新代码。

React 组件新生命周期详解

React组件老生命周期 v15.x

  1. Initialization【初始化】:state的初始化;及props是否转化为state;setup;
  2. Mounting【挂载过程】:componentWillMount()【新版删除1】->render()->componentDidMount()
  3. Updation【业务更新】:(props【父级传递的props更新;被动更新】)=>componentWillReceiveProps()【新版删除2】->shouldcomponentUpdate(){return true}-> componentWillUpdate()【新版删除3】->render()->componentDidUpdate();(states【主动调用setState更新】)=>shouldcomponentUpdate(){return true}-> componentWillUpdate()【新版删除3】->render()->componentDidUpdate()
  4. Unmounting【卸载过程】:componentWillUnmount

为什么Fiber Reconciler要有新的生命周期函数呢?

答:1.Fiber Reconciler中为了在没有更新前再次混入更新任务导致Fiber更新整个流程有点混乱;为了适配Fiber Reconciler就取消了在更新前可以再次触发更新的操作。

(有部分同学会在componentWillMount中setState;异步请求)

Fiber Reconciler要求对组件的生命周期,至少在更新前做到要纯函数行为。【不能写入异步的操作,影响更新流程】

2.我们之前并不是Fiber Reconciler中导致的,在刚开始接触React的时候会有大部分同学,会在componentWillMount进行set相关操作(setState,进行初始化redux操作,以及调用接口异步操作)【应该写在构造函数constructor中】,不然会多进行一遍vDom diff;

另一个就是componentWillUpdate中进行setState操作【不带任何条件的操作】,相当于触发了一个无线循环。

总结:基于这两点,一个是我们在老的生命周期中对一些方法的滥用,以及为了适配Fiber Reconciler当中更新前的一些流程处理,是为了我们后面的异步渲染做准备,所以React16.x之后就更新了新的生命周期函数。

 

新的组件生命周期

React v16.3版本

static getDerivedStateFromProps(props, state)【替换componentWillReceiveProps】、static getSnapshotBeforeUpdate【静态方法,静态方法中不能调用this】

1.挂载时:constructor()【构造函数】->getDerivedStateFromProps()【新增1】->render()->React更新DOM和refs->componentDidMount()

2.更新时:New Props触发更新 =>getDerivedStateFromProps()【新增1】->shouldComponentUpdate(){return true}->render()->getSnapshotBeforeUpdate()【新增2】->React更新DOM和refs->componentDidUpdate()

setState()触发更新=>shouldComponentUpdate(){return true}->render()->getSnapshotBeforeUpdate()【新增2】->React更新DOM和refs->componentDidUpdate()

forceUpdate()触发更新=>render()->getSnapshotBeforeUpdate()【新增2】->React更新DOM和refs->componentDidUpdate()

3.卸载时:componentWillUnmount()

Rebder(更新)阶段【render()方法之前】”:纯净【纯函数】且不包含副作用【重新触发setState、异步请求、redux更新】。可能会被React暂停,中止或重新启动。

Pre-commit阶段”:可以读取DOM

Commit阶段”:可以使用DOM,运行副作用,安排更新。

React v16.4版本【通常用的v16.4版本】

与v13比

挂载阶段【constructor】和更新阶段【New Props,setState(),forceUpdate()】之后都会触发getDerivedStateFromProps()

getDerivedStateFromProps

是一个派生state,所有可能触发state变更的都会经过这个静态方法,主要是返回一个派生类的state

 

挂载阶段

挂载阶段的函数

  • constructor 构造函数,初始化state,以及为事件处理函数绑定实例。【初始化数据】
  • getDerivedStateFromProps (nextProps, state) { this === window } 新增的静态方法。返回一个新的state,或者是null(后续不更新)。
  • render 渲染函数。
  • componentDidMount 挂载成功后立即调用的函数。【副作用操作,调用fetch(接口数据),绑定真实dom数据,如window.onresize,window.onscroll事件等】

更新阶段

更新阶段的函数

  • getDerivedStateFromProps props变化或者state方法触发。
  • shouldComponentUpdate 判断是否进行更新。【可以对UI更新逻辑进行优化】
  • render 渲染函数。
  • getSnapshotBeforeUpdate render方法之后调用,返回一个dom更改之前的快照,将配合后续的componentDidUpdate方法使用。
  • componentDidUpdate(oldprops, oldstate) 更新后会被立即调用。如果设置了getSnapshotBeforeUpdate(),会多出一个componentDidUpdate(oldprops, oldstatesnapshot);异步,进行setState操作,要进行条件判断,避免死循环更新,

卸载阶段

卸载阶段的函数

  • componentWillUnmount 卸载函数,组件卸载及销毁之前直接调用。主要用于清除一些在组件生命周期订阅,真实DOM事件以及setTimeout/setInterval的返回值。【不做的话,可能会引起内存泄漏、溢出】

异常捕获

v16.x 异常捕获的函数【全局错误处理,后代组件异常处理】

  • componentDidCatch(error,info) 生命周期方法在后代组件抛出错误后被调用。方法接收两个参数(error,info),分别是错误信息和错误组件的栈信息。;做一些错误日志上传,错误信息,错误源。不推荐在这里修改state,处理UI页面展示。避免setState影响Fiber 协调
  • getDerivedStateFromError(error) 在后代组件抛出错误后调用,接收一个参数(error)表示具体错误信息。做一些兼容错误页面,返回一些对象,控制页面元素,用户体验更好,是否出现不可抗性错误。新增的静态类型,返回一个派生类的state,建议在这里修改state进行页面处理

v15.x之前的处理方案:

1.关键代码加try{}catch(e){}包裹

2.监听window.onerror方案。也可以通过window.addEventListener("error", function(evt){})

3.react 提供的一个内置捕获错误方法:unstable_handleError;没有正式对外宣布过,并不是一个标准的稳定的方法

新版组件升级

升级组件版本

  • componentWillMount
    • render方法之前调用,在此调用setState并不会触发再次渲染。
    • 通常会在这个方法中进行页面标题的一些修改以及其他与再次render不相关的操作。
  • UNSAFE_componentWillMount(不推荐用这个替换componentWillMount)
    • 与state相关的操作挪到constructor方法中执行。
    • 异步操作挪到componentDidMount中执行。
  • componentWillUpdate
    • 在组件收到新的props或者state时,会在渲染之前调用。
    • 方法内不能调用setState,触发循环,内存泄漏。
  • UNSAFE_componentWillUpdate(官方保留方法,不推荐使用)
    • 应该在shouldComponentUpdate中判断是否更新。
  • componentWillReceiveProps
    • 接收父级组件传递过来最新的props,转化为组件内的state。
    • 判断是否进行更新或者执行异步请求数据。
  • UNSAFE_componentWillReceiveProps(官方保留方法,不推荐使用)
    • 与渲染相关的props直接渲染,不需要处理为组件内state。
    • 异步数据请求在componentDidUpdate中处理。
    • getDerivedStateFromProps方法替换,需要考虑生命周期的执行顺序。【挂载阶段【constructor】和更新阶段【New Props,setState(),forceUpdate()】之后都会触发getDerivedStateFromProps()

APP.js

import React, { Component } from "react";
import NewCycle from "./component";
import "./styles.css";
const mockList = [{key: 1,text: "这是列表项-1"},{key: 2,text: "这是列表项-2"},{key: 3,text: "这是列表项-3"},{key: 4,text: "这是列表项-4"}
];
export default class App extends Component {// let cycleList = [];state = {cycleList: []};// const [cycleList, setCycleList] = useState([]);queryList = () => {this.setState({cycleList: mockList});};render() {return (<div className="App"><NewCyclecycleList={this.state.cycleList}queryListCB={this.queryList}/></div>);}
}

component.js

import React, { Component } from "react";
import shallowequal from "shallowequal";// 开源第三方库,shallowequal比较值相等,或者对象含有相同的属性、且属性值相等
export default class NewCycle extends Component {constructor(props) {super(props);this.state = {list: [],parentList: []};}/* UNSAFE_componentWillReceiveProps(nextProps) {if (!shallowequal(this.props, nextProps)) {const { cycleList } = nextProps;this.setState({list: cycleList.map(item => ({...item,label: "origin" // 组件内部要调用一些逻辑}))});}} componentDidUpdate(prevProps, prevState) {// console.log(prevProps, prevState, this.props, this.state);// 比getDerivedStateFromProps晚一些,更新完成之后才触发if (!shallowequal(this.props, prevProps)) {const { cycleList } = this.props;this.setState({list: cycleList.map((item) => ({...item,label: "标题"}))});}}*/static getDerivedStateFromProps(props, state) {// newprops,oldstate// 触发时机有4种,要做好兼容判断const { cycleList } = props;const { parentList } = state;/*** prueComponent 在这里如果返回有数据的对象,* shouldComponentUpdate 会返回true* 最好是不要再用state来控制*///  初始化不执行         &&if (cycleList.length > 0 && !shallowequal(cycleList, parentList)) {return {list: cycleList.map((item) => ({...item,label: "标题"})),parentList: cycleList};}return null;}queryList = () => {const { queryListCB } = this.props;if (typeof queryListCB === "function") {queryListCB();}};render() {const { list } = this.state;return (<div>{list.map(item => (<div key={item.key}>{item.label}-{item.text}</div>))}<button onClick={this.queryList}>按钮</button></div>);}
}

升级组件遍布-保留选项

老工程代码量很多,改动特别麻烦。需要回归的点非常多!怎么解决?

npx react-codemod rename-unsafe-lifecycles 
// 此方法会给需要添加'UNSAFE_'的方法加上它。 此时版本为【v16.x】 (v15.x < v16.x < v17)

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

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

相关文章

基于grpc从零开始搭建一个准生产分布式应用(6) - 02 - MapStruct数据转换

一、基础转换 1.1、基础类型 基本类型、包装类、BigDecimal转String默认使用DecimalFormat格式化&#xff0c;Mapping#numberFormat可以指定格式&#xff0c;Date转String默认使用SimpleDateFormat格式化&#xff0c;如默认格式不符要求&#xff0c;可以用&#xff0c;Mapping…

53 个 CSS 特效 3(完)

53 个 CSS 特效 3&#xff08;完&#xff09; 前两篇地址&#xff1a; 53 个 CSS 特效 153 个 CSS 特效 2 这里是第 33 到 53 个&#xff0c;很多内容都挺重复的&#xff0c;所以这里解释没之前的细&#xff0c;如果漏了一些之前的笔记会补一下&#xff0c;写过的就会跳过。…

Error: PostCSS plugin autoprefixer requires PostCSS 8 问题解决办法

报错&#xff1a;Error: PostCSS plugin autoprefixer requires PostCSS 8 原因&#xff1a;autoprefixer版本过高 解决方案&#xff1a; 降低autoprefixer版本 执行&#xff1a;npm i postcss-loader autoprefixer8.0.0

【配置环境】Visual Studio 配置 OpenCV

目录 一&#xff0c;环境 二&#xff0c;下载和配置 OpenCV 三&#xff0c;创建一个 Visual Studio 项目 四&#xff0c;配置 Visual Studio 项目 五&#xff0c;编写并编译 OpenCV 程序 六&#xff0c;解决CMake编译OpenCV报的错误 一&#xff0c;环境 Windows 11 家庭中…

Super Resolve Dynamic Scene from Continuous Spike Streams论文笔记

摘要 近期&#xff0c;脉冲相机在记录高动态场景中展示了其优越的潜力。不像传统相机将一个曝光时间内的视觉信息进行压缩成像&#xff0c;脉冲相机连续地输出二的脉冲流来记录动态场景&#xff0c;因此拥有极高的时间分辨率。而现有的脉冲相机重建方法主要集中在重建和脉冲相…

C语言入门 Day_12 一维数组0

目录 前言 1.创建一维数组 2.使用一维数组 3.易错点 4.思维导图 前言 存储一个数据的时候我们可以使用变量&#xff0c; 比如这里我们定义一个记录语文考试分数的变量chinese_score&#xff0c;并给它赋值一个浮点数&#xff08;float&#xff09;。 float chinese_scoe…

解决WebSocket通信:前端拿不到最后一条数据的问题

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

CTFhub-SSRF-内网访问

CTFHub 环境实例 | 提示信息 http://challenge-8bf41c5c86a8c5f4.sandbox.ctfhub.com:10800/?url_ 根据提示&#xff0c;在url 后门添加 127.0.0.1/flag.php http://challenge-8bf41c5c86a8c5f4.sandbox.ctfhub.com:10800/?url127.0.0.1/flag.php ctfhub{a6bb51530c8f6be0…

自动化运维:Ansible之playbook基于ROLES部署LNMP平台

目录 一、理论 1.playbook剧本 2.ROLES角色 3.关系 4.Roles模块搭建LNMP架构 二、实验 1.Roles模块搭建LNMP架构 三、问题 1.剧本启动php报错语法问题 2.剧本启动mysql报错语法问题 3.剧本启动nginx开启失败 4.剧本安装php失败 5.使用yum时报错 6.rpm -Uvh https…

springsecurity+oauth 分布式认证授权笔记总结12

一 springsecurity实现权限认证的笔记 1.1 springsecurity的作用 springsecurity两大核心功能是认证和授权&#xff0c;通过usernamepasswordAuthenticationFilter进行认证&#xff1b;通过filtersecurityintercepter进行授权。springsecurity其实多个filter过滤链进行过滤。…

11 - 深入了解NIO的优化实现原理

Tomcat 中经常被提到的一个调优就是修改线程的 I/O 模型。Tomcat 8.5 版本之前&#xff0c;默认情况下使用的是 BIO 线程模型&#xff0c;如果在高负载、高并发的场景下&#xff0c;可以通过设置 NIO 线程模型&#xff0c;来提高系统的网络通信性能。 我们可以通过一个性能对比…

STM32f103入门(8)TIM输入捕获输入捕获测频率PWMI测占空比

TIM输入捕获 频率测量输入捕获基本结构PWMI基本结构主从触发模式输入捕获测量频率PWMI测占空比 频率测量 输入捕获基本结构 CNT计数一个周期&#xff0c;转运到CCR1里面去&#xff0c;CNT0 这时候CCR1N FxFc/N Fc cnt的驱动时钟 这时候就可以得到频率 Fc72M/PSC PWMI基本结构 …

设计模式之组合模式

文章目录 一、介绍二、案例 一、介绍 组合模式(Composite Pattern)&#xff0c;属于结构型设计模式。组合模式常用于树形的数据结构&#xff0c;比如&#xff1a;多级菜单、部门层级关系、html文本中的dom树。它的特点是使用户对单个对象和组合对象的使用是相同的。 二、案例…

mac制作ssl证书|生成自签名证书,nodejs+express在mac上搭建https+wss(websocket)服务器

注意 mac 自带 openssl 所以没必要像 windows 一样先安装 openssl&#xff0c;直接生成即可 生成 ssl/自签名 证书 生成 key # 生成rsa私钥&#xff0c;des3算法&#xff0c;server_ssl.key是秘钥文件名 1024位强度 openssl genrsa -des3 -out server_ssl.key 1024让输入两…

走进低代码平台| iVX-困境之中如何突破传统

前言&#xff1a; “工欲善其事,必先利其器”&#xff0c;找到和使用一个优质的工具平台&#xff0c;往往会事半功倍。 文章目录 1️⃣认识走近低代码2️⃣传统的低代码开发3️⃣无代码编辑平台一个代码生成式低代码产品iVX受面性广支持代码复用如何使用&#xff1f; 4️⃣总结…

如何自定义iview树形下拉内的内容

1.使用render函数给第一层父级定义 2. 使用树形结构中的render函数来定义子组件 renderContent(h, {root, node, data}) {return data.children.length0? h(span, {style: {display: inline-block,width: 400px,lineHeight: 32px}}, [h(span, [h(Icon, {type: ios-paper-outli…

PY32F003F18P单片机概述

PY32F003F18P单片机是普冉的一款ARM微控制器&#xff0c;内核是Cortex-M0。这个单片机的特色&#xff0c;就是价格便宜&#xff0c;FLASH和SRAM远远超过8位单片机&#xff0c;市场竞争力很强大。 一、硬件资源&#xff1a; 1)、FLASH为64K字节&#xff1b; 2)、SRAM为8K字节&…

解决gitee仓库中 .git 文件夹过大的问题

最近&#xff0c;许多项目都迁移到gitee。使用的也越来越频繁&#xff0c;但是今天突然收到一个仓库爆满的提示。让我一脸懵逼。本文将详细为你解答&#xff0c;这种情况如何处理。 1、起因 我收到的报错如下&#xff1a; remote: Powered by GITEE.COM [GNK-6.4] remote: T…

车载监管模块项目需求分析报告

目录 1 文档说明.......................................................................................... 4 2 参考文件.......................................................................................... 4 3 概述.......................................…

YOLOv7框架解析

YOLOv7概念 YOLOv7是基于YOLO系列的目标检测算法&#xff0c;由Ultra-Light-Fast-Detection&#xff08;ULFD&#xff09;和Scaled-YOLOv4两种算法结合而来。它是一种高效、准确的目标检测算法&#xff0c;具有以下特点&#xff1a; 1. 高效&#xff1a;YOLOv7在保持准确率的…