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 +1
    this.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调用时机,属于业务开发中实用知识点,感觉还行的看客老爷们给个赞吧!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【三维重建】摄像机几何

针孔相机模型 为了方便我们对针孔相机模型进行数学建模&#xff0c;我们往往对虚拟像平面进行研究&#xff0c;因为虚拟像平面的方向与我们实际物体的方向一致。 通过相似三角形法可以得到三维坐标到二维坐标映射 将像平面原点坐标移动到左下角&#xff1a; 加上现实世界单位&a…

Excel表列序号

题意&#xff1a; 给你一个字符串 columnTitle &#xff0c;表示 Excel 表格中的列名称。返回 该列名称对应的列序号 。 例如&#xff1a; A -> 1 B -> 2 C -> 3 … Z -> 26 AA -> 27 AB -> 28 … 示例 1: 输入: columnTitle “A” 输出: 1 示例 2: 输…

植物补光灯,哪种效果好?

室内种植物有诸多好处&#xff1a;空间装饰、吸收有害物质、释放氧气&#xff0c;使室内空气更加清新&#xff1b;植物的蒸腾作用可以增加室内的湿度&#xff0c;改善秋冬季干燥的室内环境&#xff0c;可谓是天然的加湿器。 然而由于缺乏太阳光&#xff0c;在室内养植并不是一…

Matlab设置figure中标题/图例英文不同字体

1.创建一个曲线图 x linspace(-10,10,200); y sin(4*x)./exp(x); plot(x,y) xlim([0 10]) ylim([-0.4 0.8]) xlabel(a); ylabel(b); title(曲线图sapi); set(gca,FontName,Times New Roman,fontsize,16); legend(曲线12)标题中既包含英文又包含中文&#xff0c;如果设置字体…

玩具品牌的国际化之路:市场推广战略解析

玩具产业一直是全球市场中备受瞩目的领域之一。随着全球化的发展和互联网的普及&#xff0c;越来越多的玩具品牌开始进军国际市场。这既是机遇&#xff0c;也是挑战。在竞争激烈的全球市场中&#xff0c;如何成功推广玩具品牌是一个关键的问题。本文Nox聚星将和大家探讨玩具品牌…

一台主机上只能保持最多 65535 个 TCP 连接吗?

大家好&#xff0c;我是老杨。 在知乎上刷到一个问题&#xff0c;叫做“一台主机上只能保持最多 65535 个 TCP 连接吗&#xff1f;” 关注度极高&#xff0c;想着咱们粉丝也一定有兴趣&#xff0c;就展开聊一聊。 对技术感兴趣&#xff0c;是做我们这一行必须要有的品质之一…

6大顶级团队计划目标管理软件盘点,全行业适用!

在快节奏的现代工作环境中&#xff0c;高效的团队计划和执行是团队取得成功的关键。然而&#xff0c;随着团队规模不断增大、工作任务不断增加&#xff0c;如何提高团队计划与效率成为了一个挑战。幸运的是&#xff0c;有许多先进的软件工具可以帮助团队更好地组织、协调和追踪…

【Python基础】基于UPD协议实现简易聊天室(Socket编程)

UDP通信 1.什么是 socket2. 创建 socket3.udp 网络程序-发送、接收数据&#xff08;User Datagram Protocol&#xff09;udp 网络程序-发送、接收数据&#xff08;客户端&#xff09;udp 绑定信息udp 绑定信息---服务器端总结 4.udp 聊天器 1.什么是 socket socket(简称 套接字…

遍历List集合和Map进行修改和删除报java.util.ConcurrentModificationException错误详解

一、异常产生 当我们使用foreach迭代一个ArrayList或者HashMap时&#xff0c;如果尝试对集合做一些修改操作&#xff08;例如删除元素或新增&#xff09;&#xff0c;可能会抛出java.util.ConcurrentModificationException的异常。 javapublic static void main(String[] args)…

ChatGPT显现“ Something went wrong. If this issue persists ...”什么原因?如何解决?

一、报错提示 Something went wrong. If this issue persists please contact us through our help center at help.openai.com. 二、解决方案 一般是代理节点出现问题 ChatGPT退出登录 关闭代理并重新启动代理 切换其他节点 清除浏览器缓存 重新登录ChatGPT 三、其它思路…

C# TabControl实现为每一个TabPage添加关闭按钮

默认情况下TabControl是无法通过界面关闭TabPage的 有些情况下我们需要手动关闭任意一个TabPage&#xff0c;如下图所示 TabControl控件自带属性是无法满足以上需求&#xff0c;下面简单介绍实现过程 1、首先需要对TabPage进行重绘&#xff0c;其目的是为了在TabPage上画出…

Linux学习第38天:Linux I2C 驱动实验(二):哥俩好

Linux版本号4.1.15 芯片I.MX6ULL 大叔学Linux 品人间百味 思文短情长 本节笔记主要学习I2C设备驱动编写及硬件原理图分析。 先把整个本节的思维导图贴出来&#xff1a; 二、I.MX6U的I2C适配器驱动分析 适配器驱动一般都是由SOC厂商提…

乌镇峰会十年之约,为什么IBM是那颗最亮的星?

&#xff08;IBM董事长兼首席执行官Arvind Krishna&#xff09; 2023年处于世界互联网下一个50年开端的头五年。54年前的1969年&#xff0c;世界互联网诞生&#xff1b;同年&#xff0c;IBM助力“阿波罗”号登月成功、首次将人类宇航员送上了月球&#xff1b;当时&#xff0c;…

React Native适配Xcode 15 iOS 17.0+

iOS 17.0 Simulator(21A328)下载失败 App Store 更新到 Xcode15 后&#xff0c;无法运行模拟器和真机。需要下载iOS 17对应的模拟器。Xcode中更新非常容易中断失败&#xff0c;可以在官网单独下载iOS 17模拟器文件&#xff0c;例如&#xff1a;iOS_17.0.1_Simulator_Runtime.d…

WPS表格无法粘贴信息,原因是复制区域与粘贴区域形状不同

WPS表格无法粘贴信息&#xff0c;原因是复制区域与粘贴区域形状不同 问题描述 我是选中了一整列&#xff0c;复制&#xff0c;但是无法粘贴到另一个EXCEL表格中 原因 首先我的数据量很大&#xff0c;有20万行&#xff0c;然后需要复制的EXCEL是.xls格式的&#xff0c;.xls格…

ros1 基础学习07 - 模拟客户端生成小乌龟服务请求生成小乌龟

模拟客户端生成小乌龟服务请求生成小乌龟 一、话题模型二、创建功能包三 创建客户端Client代码四 配置CMakeLists.txt编译规则&#xff1a;五 测试启动ros 主服务启动小乌龟的服务启动模型客户端服务 一、话题模型 Sever端是海龟仿真器/turtlesim&#xff0c;Client端是待实现…

leetcode:2485. 找出中枢整数(python3解法)

难度&#xff1a;简单 给你一个正整数 n &#xff0c;找出满足下述条件的 中枢整数 x &#xff1a; 1 和 x 之间的所有元素之和等于 x 和 n 之间所有元素之和。 返回中枢整数 x 。如果不存在中枢整数&#xff0c;则返回 -1 。题目保证对于给定的输入&#xff0c;至多存在一个中…

ChatGPT和API发生重大中断!

11月9日凌晨&#xff0c;OpenAI在官网发布&#xff0c;ChatGPT和API发生重大中断&#xff0c;导致全球所有用户无法正常使用&#xff0c;宕机时间超过2小时。 目前&#xff0c;OpenAI已经找到问题所在并进行了修复&#xff0c;但仍然不稳定&#xff0c;会继续进行安全监控。 …

3.前端调式

1. Elements 先来看这张图最上头的一行是一个功能菜单&#xff0c;每一个菜单都有它相应的功能和使用方法&#xff0c;依次从左往右来看 箭头按钮 用于在页面选择一个元素来审查和查看它的相关信息&#xff0c;当我们在Elements这个按钮页面下点击某个Dom元素时&#xff0c;箭…

[量化投资-学习笔记008]Python+TDengine从零开始搭建量化分析平台-CCI和ATR

目录 1. 指标简介CCIATR 2. 程序编写题外话 1. 指标简介 将这两个指标放在一起&#xff0c;一方面是因为这两个指标都属于摆动指数&#xff0c;可以反应市场的活跃度。 另一方面是因为CCI和ATR与之前提到的EMA,MACD,布林带的三个指标的计算基础不同。之前的三个指标都是以收盘…