react类式组件的生命周期和useEffect实现函数组件生命周期

概念

生命周期是一个组件丛创建,渲染,更新,卸载的过程,无论是vue还是react都具有这个设计概念,也是开发者必须熟练运用的,特别是业务开发,不同的生命周期做不同的事是很重要的.

....
多说两句心得,本人是先接触vue的,无论是vue2还是vue3的生命周期,在理解和学习上都会比react更容易理解,我在学习react的时候,也经常会想着这个api如果在vue里面会和哪个api功能相同.

其实有些本末倒置了,先有react才有的vue,vue是作者做了更多的操作,让你用到更舒适的api,还是那个经典形容,react是手动打,vue是自动挡.

废话不多说,开始说react的生命周期

...

如果想直接死记硬背八股文,直接拉到底看总结就可以了

类式组件

在hooks出来之前,写react基本都是用类式组件

两个原因,一是对this这个东西有特别的喜爱(vue后遗症),二是类式组件可以使用生命周期和state,适合开发业务组件.

测试各个钩子函数的demo
import React, { Component} from 'react'
export default class index extends Component {constructor(){super()console.log(this,'constructor---构造器')}state = {num:1}add = ()=>{let newNum = this.state.num +1this.setState({num:newNum})}//生命周期钩子(旧的)
//  componentWillMount =()=>{
//     console.log('componentWillMount---组件将要加载')
//  }//  componentWillUpdate = ()=>{
//     console.log('componentWillUpdate','组件将要更新')
//  }//生命周期钩子(新的)
static getDerivedStateFromProps = ()=>{console.log(this,'getDerivedStateFromProps---初始化一些基础状态')return null
}getSnapshotBeforeUpdate = ()=>{console.log(this,'getSnapshotBeforeUpdate---更新之前的快照')return '旧的值'
}//新旧都具备的shouldComponentUpdate = ()=>{console.log(this,'shouldComponentUpdate','组件需要更新')return true}componentDidUpdate = ()=>{console.log(this,'componentDidUpdate','组件更新完毕')}componentDidMount = ()=>{console.log(this,'componentDidMount---组件加载完成')}updateCallBack = ()=>{this.forceUpdate()}render() {console.log(this,'render---渲染函数')return (<div id='index'><h3>生命周期模块</h3> <button onClick={this.add}>修改一下数值</button><p>{this.state.num}</p><button onClick={this.updateCallBack}>手动更新</button><br /></div>)}componentWillUnmount = ()=>{console.log(this,'componentWillUnmount---组件将要卸载')}
}

场景:

1.页面初次加载

constructor > getDerivedStateFromProps > render > componentDidMount

2.点击修改一下数值按钮

getDerivedStateFromProps > shouldComponentUpdate > render > getSnapshotBeforeUpdate >

componentDidUpdate

 3.手动更新(forceUpdate函数)

getDerivedStateFromProps > render > getSnapshotBeforeUpdate > componentDidUpdate

 4.卸载当前组件

componentWillUnmount

生命周期经典图

解读一下:

好吧,其实没有什么太多好解读的,本人的react内力没有那么深厚,这张图就是刚才我们实验的结果

初始化,自动更新,手动更新,卸载

你只要把这个demo自己写一下,就瞬间知道这个图是干啥的了,除了很长的单词比较难写,其余都好说.

你以为这样就完了吗,不不不,没有没有没有.这里还有两个需要专门说的

两个疑问
1.生命周期连续调用了两次的问题

造成这个原因是因为你的根组件使用了严格模式 React.StrictMode

ReactDOM.createRoot(document.getElementById('root')).render(<Provider store={store}>{/* <React.StrictMode> 把它注释掉就可以了*/}   <App />{/* </React.StrictMode> */}</Provider>
)
2.父子组件生命周期顺序(测试demo)

初始化

父costructor > 父 getDerviedStateFromProps > 父render >子costructor >子getDerviedStateFromProps > 子render > 子componentDidMount >父componentDidMount

 父组件修改值触发更新

父 getDerivedStateFromProps > 父 shouldComponentUpdate > 父 render > 子 getDrivedStateFromprops > 子shouldComponentUpdate > 子 render > 子 getSnaphotBeforeUpdate > 父getSnapshotBeforeUpdate > 子 componentDidUpdate> 父 componentDidUpdate

父组件手动更新

父 getDerivedStateFromProps > 父render > 子 getDerivedStateFromProps > 子 shouldComponentUpdate > 子render > 子getSnapshotBeforeUpdate > 父getSnapshotBeforeUpdate > 子componentDidUpdate > 父componentDidUpdate

 组件卸载

父componentWillUnmount > 子componentWillUnmount

函数组件

函数组件实现生命周期是需要借助一个api的,这个api叫做useEffect.

demo
import React,{useState,useEffect} from 'react'
import {Button} from 'antd'
export default function index(props) {const [num1,changeNum1] = useState(0)const [num2,changeNum2] = useState(10)//单个-----------------------------------------------------//首次加载,修改num1,修改num2,卸载当前组件没有useEffect(()=>{console.log('只传一个函数')})//首次加载,num1没有,num2没有,卸载当前组件没有useEffect(()=>{console.log('参数二传一个空数组')},[])//首次加载,修改num1,num2没有,卸载当前组件没有useEffect(()=>{console.log('传参数num1')},[num1])//首次加载,num1没有,修改num2,卸载当前组件没有useEffect(()=>{console.log('传参数num2')},[num2])//首次加载,修改num1,修改num2,卸载当前组件没有useEffect(()=>{console.log('都传')},[num1,num2])//首次没有,修改num1,修改num2,卸载组件调用useEffect(()=>{return ()=>{console.log('return方法')}})// 总结:// 1.参数1:函数:   初始化和每次修改参数都会触发这个函数// 2.参树2:空数组: 只有首次加载会触发// 3.参数2:某条数据: 首次加载和修改该数据都会触发// 4.参数2:多条数据: 首次加载和修改数组内任意一条数据都会触发// 5.参数1:函数返回一个函数: 首次不急在,但是修改任意数值和卸载组件时都会调用return (<div><p>数值1:{num1}<Button onClick={()=>changeNum1(num1+1)}>修改数值1</Button></p><p>数值2:{num2}<Button onClick={()=>changeNum2(num2-1)}>修改数值2</Button></p></div>)
}

 初始化

 修改值1

组件卸载

实现初始化,更新,单独的数据更新,卸载
import React,{useState,useEffect} from 'react'
import {Button} from 'antd'
export default function index(props) {const [num1,changeNum1] = useState(0)const [num2,changeNum2] = useState(10)// 组合------------------------------------------------------// 场景1: 初始化加载useEffect(()=>{console.log('初始化加载')console.log(num1,'???',props)},[])//场景2: 任意数据更新,但是初始化不加载useEffect(()=>{return ()=>{console.log('数据发生修改了')}})//场景3: 只有卸载时加载useEffect(()=>{return ()=>{console.log('卸载才会调用')}},[])//场景4: 某一数据发生改变,单独触发useEffect(()=>{return ()=>{console.log('只有修改num1才会调用')}},[num1])return (<div><p>数值1:{num1}<Button onClick={()=>changeNum1(num1+1)}>修改数值1</Button></p><p>数值2:{num2}<Button onClick={()=>changeNum2(num2-1)}>修改数值2</Button></p></div>)
}

总结

类式组件
各阶段钩子调用顺序
初始化constructor > getDerivedStateFromProps > render > componentDidMount
自动更新

getDerivedStateFromProps > shouldComponentUpdate > render > getSnapshotBeforeUpdate >

componentDidUpdate 

手动更新getDerivedStateFromProps > render > getSnapshotBeforeUpdate > componentDidUpdate
卸载componentWillUnmount
父子组件生命周期
初始化父costructor > 父 getDerviedStateFromProps > 父render >子costructor >子getDerviedStateFromProps > 子render > 子componentDidMount >父componentDidMount
父组件自动更新父 getDerivedStateFromProps > 父 shouldComponentUpdate > 父 render > 子 getDrivedStateFromprops > 子shouldComponentUpdate > 子 render > 子 getSnaphotBeforeUpdate > 父getSnapshotBeforeUpdate > 子 componentDidUpdate> 父 componentDidUpdate
父组件手动更新父 getDerivedStateFromProps > 父render > 子 getDerivedStateFromProps > 子 shouldComponentUpdate > 子render > 子getSnapshotBeforeUpdate > 父getSnapshotBeforeUpdate > 子componentDidUpdate > 父componentDidUpdate
卸载父componentWillUnmount > 子componentWillUnmount
钩子函数连续调用两次的问题解决

干掉根组件的 React.StrictMode

函数组件
只在初始化加载调用

    useEffect(()=>{

        console.log('初始化加载')

    },[])

初始化不调用但是更新组件会调用

    useEffect(()=>{

        return ()=>{

            console.log('数据发生修改了')

        }

    })

单独的数据发生变化进行调用

    useEffect(()=>{

        return ()=>{

            console.log('只有修改num1才会调用')

        }

    },[num1])

只在组件卸载时调用

    useEffect(()=>{

        return ()=>{

            console.log('卸载才会调用')

        }

    },[])

尾声

我的这篇博客没有专门讲这些api在调用时都发生了啥,主要是让读者了解react生命周期的api调用时机,属于业务开发中实用知识点,感觉还行的看客老爷们给个赞吧!

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

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

相关文章

Spring IoC注解式开发

2023.11.11 注解的存在主要是为了简化XML的配置。Spring6倡导全注解开发。 负责声明Bean的注解&#xff0c;常见的包括四个&#xff1a; ComponentControllerServiceRepository 通过源码可以发现&#xff0c;Controller、Service、Repository这三个注解都是Component注解的别名…

【pytorch深度学习】使用张量表征真实数据

使用张量表征真实数据 本文为书pytorch深度学习实战的一些学习笔记和扩展知识&#xff0c;涉及到的csv文件等在这里不会给出&#xff0c;但是我会尽量脱离这一些文件将书本想要表达的内容给展示出来。 文章目录 使用张量表征真实数据1. 加载图像文件2. 改变布局3. 加载目录下…

【Gradle-12】分析so文件和依赖的关系

1、前言 在包大小的占比中&#xff0c;so文件的占比往往是最高的&#xff0c;动辄几兆的大小多一个都会把包大小的指标打爆。 而在各厂商要求对手机CPU ARM架构进行分包适配的情况下&#xff0c;你更需要知道哪些依赖是没有适配v7a/v8a的&#xff0c;这将影响你的APP在应用市场…

Vue3 + Naive-ui Data Table 分页页码显示不全

当使用naive-ui 表格并且使用分页组件的时候 需要增加 remote

C++使用线程池模拟异步事件处理机制

在C很多框架中都有异步事件处理机制&#xff0c;这导致我们在看源码时经常很疑惑&#xff0c;难以理解&#xff0c;而其中包含的编程套路可能是一些成熟的技术&#xff0c;只是我们不熟悉&#xff0c;比如WebRTC中类似于Qt的信号槽机制&#xff0c;线程事件处理, 或者使用系统异…

Sensor 点亮出图后,颜色偏红或者偏绿是为什么?

这是因为 sensor balck level 的值配置的不正确导致&#xff0c;black level 的值一般在效果参数的 calibration 参数里面。 在驱动调试阶段&#xff0c;我们一般都是复用其他已调试好的&#xff0c;sensor 的驱动文件及效果文件&#xff0c; 而不同 sensor 的 balck level 的…

【qemu逃逸】XCTF 华为高校挑战赛决赛-pipeline

前言 虚拟机用户名: root 无密码 设备逆向与漏洞分析 程序没有去符合, 还是比较简单. 实例结构体如下: 先总体说一下流程: encode 为 base64 编码函数, decode 为 base64 解码函数. 然后 encPipe 和 decPipe 分别存放编码数据和解码数据, 分别有四个: 其中 EncPipeLine 中…

网页推理游戏

目录 python challenge &#xff08;0&#xff09; &#xff08;1&#xff09; &#xff08;2&#xff09; The Riddle &#xff08;1&#xff09; &#xff08;2&#xff09; &#xff08;3&#xff09; &#xff08;4&#xff09; Nazo &#xff08;1&#xff09;…

【Spring】SpringBoot日志

SpringBoot日志 日志概述日志使用打印日志获取日志对象使用日志对象打印日志日志框架介绍门面模式SLF4J框架介绍(simple logging facade for java) 日志格式说明日志级别日志级别的分类日志级别的使用 日志配置配置日志级别日志持久化配置日志文件的路径和文件名配置日志文件的…

【tgcalls】Instance接口的实例类的创建

tg 里有多个版本,因此设计了版本管理的map,每次可以选择一个版本进行实例创建这样,每个客户端就可以定制开发了。tg使用了c++20创建是要传递一个描述者,里面是上下文信息 G:\CDN\P2P-DEV\tdesktop-offical\Telegram\ThirdParty\tgcalls\tgcalls\Instance.cpp可以看到竟然是…

【数据结构】顺序表 | 详细讲解

在计算机中主要有两种基本的存储结构用于存放线性表&#xff1a;顺序存储结构和链式存储结构。本篇文章介绍采用顺序存储的结构实现线性表的存储。 顺序存储定义 线性表的顺序存储结构&#xff0c;指的是一段地址连续的存储单元依次存储链性表的数据元素。 线性表的&#xf…

单词规律问题

给定一种规律 pattern 和一个字符串 s &#xff0c;判断 s 是否遵循相同的规律。 这里的 遵循 指完全匹配&#xff0c;例如&#xff0c; pattern 里的每个字母和字符串 s 中的每个非空单词之间存在着双向连接的对应规律。 示例1: 输入: pattern “abba”, s “dog cat cat d…

【Git】Git分支与标签掌握这些技巧让你成为合格的码农

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《Git》。&#x1f3af;&#x1f3af; &#x1f449…

vue Sts认证后直传图片到阿里云OSS

后端进行sts认证生成临时身份凭证&#xff0c;前端通过凭证直传图片等文件到OSS中 一 OSS配置 增加用户和角色&#xff0c;创建OSS bucket 1.1 添加用户 登录阿里云管理控制台&#xff0c;右侧头像&#xff0c;进入访问控制 点击左侧导航栏的身份管理的用户&#xff0c;点击…

MySQL的索引和复合索引

由于MySQL自动将主键加入到二级索引&#xff08;自行建立的index&#xff09;里&#xff0c;所以当select的是主键或二级索引就会很快&#xff0c;select *就会慢。因为有些列是没在索引里的 假设CA有1kw人咋整&#xff0c;那我这个索引只起了前一半作用。 所以用复合索引&am…

探索微信小程序框架的精华——高质量的优秀选择

目录 引言&#xff1a; 1. 框架性能 2. 开发者工具支持 3. 文档和社区支持 4. 扩展能力 5. 使用率和稳定性 结语&#xff1a; 引言&#xff1a; 微信小程序作为一种轻量级、高效便捷的应用形式&#xff0c;已经在移动应用领域占据了重要地位。而其中&#xff0c;选择一个…

【EI会议征稿】JPCS独立出版-第五届新材料与清洁能源国际学术会议(ICAMCE 2024)

JPCS独立出版-第五届新材料与清洁能源国际学术会议&#xff08;ICAMCE 2024&#xff09; 2024 5th International Conference on Advanced Material and Clean Energy 第五届新材料与清洁能源国际学术会议&#xff08;ICAMCE 2024&#xff09;将于2024年2月23-25日在中国▪长沙…

【论文阅读】多模态NeRF:Cross-Spectral Neural Radiance Fields

https://cvlab-unibo.github.io/xnerf-web intro 从不同的light spectrum sensitivity获取信息&#xff0c;同时需要obtain a unified Cross-Spectral scene representation – allowing for querying, for any single point, any of the information sensed across spectra。…

xcode SDK does not contain ‘libarclite‘

SDK does not contain libarclite at the path /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphonesimulator.a; try increasing the minimum deployment target解决方法 iOS13以上

macOS Sonoma 14.2beta2(23C5041e)发布(附黑白苹果镜像地址)

系统介绍 黑果魏叔11 月 10 日消息&#xff0c;今日向 Mac 电脑用户推送了 macOS 14.2 开发者预览版 Beta 2 更新&#xff08;内部版本号&#xff1a;23C5041e&#xff09;&#xff0c;本次更新距离上次发布隔了 14 天。 macOS Sonoma 14.2 添加了 Music 收藏夹播放列表&…