React之生命周期

React之生命周期

旧版本,函数组件是没有生命周期的。新版本中通过useEffect触发函数的生命周期

一、基于类组件的生命周期

React的组件生命周期分为挂载阶段更新阶段销毁阶段。因为React的state不具有Vue的响应式,所以并没有create阶段

1、挂载阶段: 【组件被创建并插入到DOM中的过程】

  • constructor:组件被创建时调用,用于初始化状态和绑定方法。

  • static getDerivedStateFromProps:在组件被创建和重新渲染之前调用,用于根据props更新状态。

  • 【已废弃】componentWillMount: 组件即将挂载,已经被废弃,向下兼容请使用【UNSAFE_componentWillMount】

    • 执行1次
    • 特点:可以访问state、不能操作DOM
  • render: 对组件视图结构进行编译【必须定义的一个钩子】

    • 先默认执行1次,后去每次setState都会执行一次
    • 特点:可以访问state、不能操作DOM
  • componentDidMount: 组件挂载完成

    • 执行一次
    • 特点: 可以访问state,也能操作DOM
    • 应用场景:发送请求;初始化第三方插件
import { Component } from 'react'

export default class Home extends Component {
  state = {
    title: 'home'
  }
  clickUpdate = () => {
    this.setState({
      title: '主页'
    })
  }
  UNSAFE_componentWillMount(): void {
    console.log(this.state.title) // 'title'
    console.log(document.querySelector('.home_box')) // null
  }
  render() {
    console.log(this.state.title, 'render') // 'title'
    console.log(document.querySelector('.home_box'), 'render') // null
    return (
      <>
        <div className="home_box">{this.state.title}</div>
        <button onClick={this.clickUpdate}>获取DOM</button>
      </>
    )
  }
  componentDidMount(): void {
    console.log(this.state.title) // 'title'
    console.log(document.querySelector('.home_box')) // <div class="home_box">home</div>
  }
}

2、更新阶段【组件的props或state发生变化时的过程】

  • static getDerivedStateFromProps(props,state):在组件被重新渲染之前调用,用于根据props更新状态。[替代了componentWillReceiveProps]
  • shouldComponentUpdate: 是否要执行组件更新。如果显示的声明了该钩子,则必须返回一个布尔值,true:执行组件更新;false:不执行组件更新。如果没有显示的声明该钩子,则正常执行组件更新
    • 应用场景: 手动进行性能优化
    • 触发条件:state状态数据发生改变
    • 系统参数:nextProps: 更新后的props; nextState:更新后的state
    • 特点: 还没有完成数据和视图的更新
  • 【已废弃】componentWillUpdate: 即将执行组件更新: *已经被废弃,向下兼容请使用【UNSAFE_componentWillUpdate】
    • 触发条件:state状态数据发生改变
    • 系统参数:nextProps: 更新后的props; nextState:更新后的state
    • 特点: 还没有完成数据和视图的更新
  • render: 重新执行视图编译
    • 触发条件:state状态数据发生改变
    • 特点: 完成数据更新, 但是还没有完成视图更新
  • getSnapshotBeforeUpdate:在组件被重新渲染之前调用,用于获取更新前的DOM状态。[替换componetnWillUpdate]
  • componentDidUpdate:组件更新完成
    • 触发条件:state状态数据发生改变
    • 特点:已经完成数据和视图的更新
    • 系统参数:prevProps: 更新之前的props; prevState:更新之前的state【此时this.state是更新后的state】
    • 场景: 进行DOM操作、网络请求等副作用操作。
  • componentWillReceiveProps:组件接收的外部props属性数据发生改变的时候执行: *已经被废弃,向下兼容请使用【UNSAFE_componentWillReceiveProps】
    • 触发条件:props数据发生改变
    • 特点:已经完成数据和视图的更新
import { Component } from 'react'

export default class Home extends Component {
  state = {
    title: 'home'
  }
  clickUpdate = () => {
    this.setState({
      title: '主页'
    })
  }
  UNSAFE_componentWillMount(): void {
    console.log(this.state.title) // 'title'
    console.log(document.querySelector('.home_box')) // null
  }
  render() {
    console.log(this.state.title, 'render') // 'title'
    console.log(document.querySelector('.home_box'), 'render') // null
    return (
      <>
        <div className="home_box">{this.state.title}</div>
        <button onClick={this.clickUpdate}>获取DOM</button>
      </>
    )
  }
  componentDidMount(): void {
    console.log(this.state.title) // 'title'
    console.log(document.querySelector('.home_box')) // <div class="home_box">home</div>
  }

  // 更新阶段
  shouldComponentUpdate(
    nextProps: Readonly<{}>,
    nextState: Readonly<{ title: string }>,
    nextContext: any
  ): boolean {
    // nextProps: {}, nextState: 更新后的state, nextContext: {}
    console.log(nextProps, nextState, nextContext)
    if (this.state.title === nextState.title) {
      // 如果数据没有发生变化 则不执行组件更新, 即是不执行render()钩子
      return false
    }
    return true
  }

  // componentWillUpdate: 严格模式下eslint, 会报错
  // UNSAFE_componentWillUpdate: 这个在高版本React也废弃了, 但是在ESLint模式下也可以使用[向下兼容]
  UNSAFE_componentWillUpdate(
    nextProps: Readonly<{}>,
    nextState: Readonly<{}>,
    nextContext: any
  ): void {
    console.log(nextProps, nextState, nextContext, 'UNSAFE_componentWillUpdate')
  }

  componentDidUpdate(
    prevProps: Readonly<{}>,
    prevState: Readonly<{}>,
    snapshot?: any
  ): void {
    console.log(prevProps, prevState, snapshot, 'componentDidUpdate')
  }

  UNSAFE_componentWillReceiveProps(
    nextProps: Readonly<{}>,
    nextContext: any
  ): void {
    console.log(nextProps, nextContext, 'UNSAFE_componentWillReceiveProps')
  }
}

3、销毁阶段: 【组件从DOM中移除的过程】

  • componentWillUnmount:组件被移除前调用,可以进行清理操作,如取消定时器、取消订阅等。

4、补充

除了上述方法,还有一些其他的生命周期方法,如错误处理相关的方法(componentDidCatch、getDerivedStateFromError)和静态方法(getDerivedStateFromProps、getDerivedStateFromError)

需要注意的是,React 16.3之后,一些生命周期方法已经被废弃或改名,如componentWillMount、componentWillUpdate、componentWillReceiveProps等,建议使用新的方法来替代

  • 旧版生命周期图

在这里插入图片描述

  • 新版生命周期图
    在这里插入图片描述

二、函数组件的生命周期

React 18引入了一些新的生命周期方法,以便更好地管理组件的生命周期事件

  • useEffect: 【异步执行的,不会阻塞渲染】用于在组件挂载、更新或卸载时执行副作用操作。它可以替代旧的生命周期方法componentDidMount、componentDidUpdate和componentWillUnmount
import { useState, useEffect } from 'react'

const Home = () => {
  const [count, setCount] = useState(0)
  const add = () => {
    setCount(count + 1)
  }
  // 接收一个参数时:组件加载完成和组件状态更新时 执行
  useEffect(function () {
    console.log('zhw')
  })
  
  // 如果只希望函数挂载完后,执行一次,组件状态变化不再执行,可以传空数组
  useEffect(function () {
    console.log('zhw')
  }, [])
  
  // 接收参数二时,参数二是一个数组,用于指定依赖数据,用于当依赖数据变化时,执行一次回调
  // 1、组件挂载完后执行一次;2、仅仅当count的状态更新,执行一次
  useEffect(function () {
    console.log('zhw')
  }, [count])

  // 组件卸载之前按
  // 1、
  useEffect(function () {
    return function () {
      // 该子函数会在组件    即将卸载  和   状态更新 的时候,自动执行
      console.log('组件卸载了')
    }
  })  
  // 2、
  useEffect(function () {
    return function () {
      // 该子函数会在组件    仅仅在 即将卸载  的时候,自动执行
      console.log('组件卸载了')
    }
  }, []) 
  return (
    <>
    	<span>{count}</span>
      	<button onClick={add}>+</button>
    </>
  )
}
export default Home

  • useLayoutEffect: 在DOM更新之后同步执行[阻塞渲染],以确保在浏览器绘制之前执行副作用操作。

适用于需要在浏览器执行绘制和布局之前立即执行的副作用操作。

import { useLayoutEffect, useState } from 'react'

const Home = () => {
  const [count, setCount] = useState(0)
  const add = () => {
    setCount(count + 1)
  }
  useLayoutEffect(
    function () {
      console.log('useLayoutEffect')
    },
    [count]
  )
  return (
    <>
      <span>{count}</span>
      <button onClick={add}>+</button>
    </>
  )
}
export default Home

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

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

相关文章

第八章:list类

系列文章目录 文章目录 系列文章目录前言list的介绍及使用list的介绍list的使用list的构造函数list的迭代器list的容量list的成员访问list的增删改查 list与vector的对比总结 前言 list是STL的一种链表类&#xff0c;可以在常数范围内在任意位置进行插入和删除的序列式容器。 …

专访伊士曼中国区高管赵志伟:以创新应对新能源汽车后市场变化

受访人&#xff1a;伊士曼高性能膜事业部中国区商务总监赵志伟 新能源汽车发展至规模化阶段&#xff0c;以贴膜、保养维修为主的后市场产业迎来快速崛起&#xff0c;新能源消费者在汽车贴膜、改装和养护领域也表现出比燃油车更高频的需求度。 作为一家全球特种材料公司&#x…

MySQL~DQL查询语句

一、DQL:查询语句 1、排序查询 语法&#xff1a; order by 子句 ​ order by 排序字段1 排序方式1 &#xff0c;排序字段2 排序方2... 排序方式&#xff1a; ASC&#xff1a;升序[默认] DESC&#xff1a;降序 在SQL语句中永远排序最后 注&#xff1a; 如果有多个排序条…

立创EDA学习

学习树莓派3B的板子发现有个扩展板比较好&#xff0c;自己最好画一个&#xff0c;反正免费。 学习视频&#xff1a;立创EDA&#xff08;专业版&#xff09;电路设计与制作快速入门。 下载专业版&#xff0c;并激活。【分专业版和标准版&#xff0c;专业版也是免费的】 手机…

学习自动化测试该怎么学?6个步骤轻松拿捏

自动化测试作为脱离手工测试的基本核心内容&#xff0c;其重要性不言而喻了&#xff0c;而且我们来看近期大厂的一些招聘信息显示&#xff0c;基本上自动化测试是必备前提&#xff0c;没有这个基本就不用谈后面的问题了&#xff0c;下面我们通过联想集团的一个软件测试工程师的…

购物车功能实现(小兔鲜儿)【Vue3】

购物车 流程梳理和本地加入购物车实现 购物车业务逻辑梳理拆解 整个购物车的实现分为两个大分支, 本地购物车操作和接口购物车操作由于购物车数据的特殊性,采取Pinia管理购物车列表数据并添加持久化缓存 本地购物车 - 加入购物车实现 添加购物车 基础思想&#xff1a;如果…

Ceph社区上游正式合入openEuler原生支持,并通过CI持续验证

作为覆盖全场景应用、支持多样性算力的面向数字基础设施的开源操作系统&#xff0c;openEuler始终遵循“上游优先”的策略&#xff0c;帮助上游开源软件原生支持openEuler&#xff0c;让openEuler系操作系统的用户可以在开发、集成、使用这些开源软件或基于这些开源软件的产品和…

市面上的ipad国产触控笔怎么样?精选的性价比电容笔

要知道&#xff0c;真正的苹果品牌的那款原装电容笔&#xff0c;光是一支电容笔就价格近千元。实际上&#xff0c;平替电容笔对没有太多预算的用户是个不错的选择。一支苹果品牌的电容笔&#xff0c;价格是平替品牌的四倍&#xff0c;但电容笔的书写效果&#xff0c;却丝毫不逊…

idea如何解决导入的项目不是Maven工程(文件下面没有蓝色的方格)二

简介&#xff1a; Maven项目导入&#xff0c;idea不识别项目 解决方法&#xff1a; 选中pom.xml -- 右键 -- Add as Maven Project

技术实力加速企业上云,联想混合云获评专有云优秀案例入选混合云全景图四大方向

7月25-26日&#xff0c;由中国信息通信研究院、中国通信标准化协会联合主办的第十届可信云大会在京顺利召开。大会重磅发布了云计算白皮书&#xff08;2023年&#xff09;、《混合云产业全景图&#xff08;2023&#xff09;》、中国算力服务研究报告、中国云计算发展指数报告等…

Golang速成

目录 Golang 语言特性Golang的优势Golang 的应用场景Golang 的不足 基础语法变量的声明常量与 iotastring字符串遍历strings 包bytes 包strconv 包unicode 包 循环语句range 函数多返回值init 函数闭包import 导包匿名函数 指针defer切片 slice数组sliceslice 操作… mapmap 的…

MySQL InnoDB死锁原因及改善建议(InnoDB Deadlocks)

死锁是事务型数据库中一种现象&#xff0c;为了在高并发环境下不出错&#xff0c;数据库引入了"锁"这一数据结构来控制资源的并发访问&#xff0c;但也会导致死锁。 目录 一、死锁概念 1.1 死锁的原因 1.2 死锁监测 二、死锁演示 2.1 死锁生成过程 2.2 死锁信息查看 …

EtherNet/IP转Modbus网关以连接AB PLC

本案例为西门子S7-1200 PLC通过捷米特Modbus转EtherNet/IP网关捷米特JM-EIP-RTU连接AB PLC的配置案例。 网关分别从ETHERNET/IP一侧和MODBUS一侧读写数据&#xff0c;存入各自的缓冲区&#xff0c;网关内部将缓冲区的数据进行交换&#xff0c;从而实现两边数据的传输。 网关做为…

vue 实现拖拽效果

实现方式&#xff1a;使用自定义指令可以实现多个面板拖拽互不影响 1.自定义指令 js directives: {// 拖拽drag(el) {el.onmousedown function (e) {let x e.pageX - el.offsetLeftlet y e.pageY - el.offsetTopdocument.onmousemove function (e) {el.style.left e.pag…

【C++】C++ STL标准模板库知识点总结(秋招篇)

文章目录 前言STL的六大组件是&#xff1f;容器(container) 算法(algorithm) 迭代器(iterator) 三者的关系&#xff1f;容器分为几种&#xff1f;分别有哪些&#xff1f;关联性容器和非关联性容器有什么区别&#xff1f;Vector容器是怎么调整大小的&#xff1f;&#xff08;内存…

【MySQL】内置函数

目录 一、日期函数 1、获得年月日 2、获得时分秒 3、获得时间戳 4、在日期的基础上加日期 5、在日期的基础上减去时间 6、计算两个日期之间相差多少天 7、案例 二、字符串函数 1、获取emp表的ename列的字符集 2、要求显示exam_result表中的信息 3、求学生表中学生姓…

短视频矩阵源码/系统搭建/源码

一、短视频矩阵系统开发需要具备以下能力 短视频技术能力&#xff1a;开发人员应具备短视频相关技术能力&#xff0c;如视频编解码、视频流媒体传输等。 大数据存储和处理能力&#xff1a;短视频矩阵系统需要处理大量的视频数据&#xff0c;因此需要具备大数据存储和处理的能力…

传统商超苦战即时零售,或沦为炮灰

眼下&#xff0c;在美团闪购、京东到家、饿了么、淘宝买菜/淘鲜达、盒马&#xff0c;还有朴朴超市、叮咚买菜等一众类超市App或者平台的绝情裹挟下&#xff0c;包含沃尔玛、家乐福、永辉、大润发、联华、华润万家、步步高、中百等等这些传统商超企业巨头&#xff0c;正过得越来…

JAVA面试总结-Redis篇章(六)——数据过期策略

Java面试总结-Redis篇章&#xff08;六&#xff09;——数据过期策略 Redis数据删除策略——惰性删除Redis数据删除策略——定期删除 Redis数据删除策略——惰性删除 Redis数据删除策略——定期删除

ADS仿真低噪声放大器学习笔记

ADS仿真低噪声放大器 文章目录 ADS仿真低噪声放大器1. 安装晶体管的库文件2. 直流分析DC Tracing3. 偏置电路的设计4. 稳定性分析5. 输入匹配和输出匹配 设计要求&#xff1a; 工作频率&#xff1a;2.4~2.5GHz ISM频段 噪声系数&#xff1a;NF < 0.7 增益&#xff1a;Gain &…