React之生命周期

news2024/11/16 18:56:46

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

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

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

相关文章

Linux学习之循环处理位置参数

for处理位置参数 loopPositionFor.sh里边的内容如下&#xff1a; #!/bin/bash# show learningfor inputString in $* doif [ "${inputString}" "good" ];thenecho "learning"fi donechmod urx loopPositionFor.sh给当前用户把loopPositionFor…

linux NDK交叉编译rtmp 与 ffmpeg+rtmp交叉编译(v7a,v8a) 完成流程

最近在学RTMP,记录一下完成的编译流程 我是mac 电脑,但是mac上编译一直通过不了,后来才换到服务器上编译, 其实mac也能编译,只是最开始踩到坑里面了… 这里记录一下linux编译完整流程 环境: NDK: android-ndk-r17cFfmpeg: ffmpeg4.2.2 (高版本也可以编译)system: mac 1. …

HCIA实验四

一.实验要求&#xff1a; 1、R4为ISP&#xff0c;其上只能配置IP地址&#xff1b;R4与其他所有直连设备间均使用共有IP&#xff1b; 2、R3 - R5/6/7为MGRE环境&#xff0c;R3为中心站点&#xff1b; 3、整个网络配置OSPF环境&#xff0c;IP基于172.16.0.0/16网段划分&#x…

分享5个AI办公新玩法,1行Python代码免费实现!

大家好&#xff0c;这里是程序员晚枫&#xff0c;小破站也叫这个名。 随着ChatGPT的兴起&#xff0c;AI办公也越来越火&#xff0c;今天给大家分享5个AI办公的第三方库&#xff0c;不仅全部免费而且都可以用1行Python代码启动。 赶紧去看看吧&#xff01; 1、智能聊天机器人…

关于minio的简单使用

最近在学习minio相关知识&#xff0c;小小的记录一下学习内容 MinIO 是一个基于Apache License v2.0开源协议的对象存储服务。它兼容亚马逊S3云存储服务接口&#xff0c;非常适合于存储大容量非结构化的数据&#xff0c;例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等…

【自动化测试】Selenium IDE脚本编辑与操作

之前&#xff0c;我们录制脚本时是录制鼠标和键盘的所有在浏览器的操作&#xff0c;那么脚本会出现多余的步骤&#xff0c;有时候我们需要手动填写脚本或修改脚本&#xff0c;所以我们有必要对selenium IDE脚本编辑与操作有所了解&#xff1b;&#xff08;采用录制的方式很容易…

如何解决大数据下滚动页面卡顿问题

原文合集地址如下&#xff0c;有需要的朋友可以关注 本文地址 合集地址 前言 之前遇到不分页直接获取到全部数据&#xff0c;前端滚动查看数据&#xff0c;页面就听卡顿的&#xff0c;当然这和电脑浏览器性能啥的还是有点关系。但根源还是一次性渲染数据过多导致的&#xf…

【Git】初始化仓库配置与本地仓库提交流程

目录 一、仓库配置邮箱与用户名 二、本地仓库提交流程 一、仓库配置邮箱与用户名 【Git】Linux服务器Centos环境下安装Git与创建本地仓库_centos git仓库搭建_1373i的博客-CSDN博客https://blog.csdn.net/qq_61903414/article/details/131260033?spm1001.2014.3001.5501 在…

JavaScript基础篇(61-70题)

此文章&#xff0c;来源于印客学院的资料【第一部分&#xff1a;基础篇(105题)】&#xff0c;也有一些从网上查找的补充。 这里只是分享&#xff0c;便于学习。 诸君可以根据自己实际情况&#xff0c;自行衡量&#xff0c;看看哪里需要加强。 概述如下&#xff1a; 希望获取…

2023年深圳杯A题赛题详细解析1.1版本

A题 影响城市居民身体健康的因素分析 附件A1是某市卫生健康研究部门对部分居民所做的“慢性非传染性疾病及其相关影响因素流行病学”调查问卷表&#xff0c;附件A2是相应的调查数据结果&#xff0c;附件A3是中国营养学会最新修订的《中国居民膳食指南》中为平衡居民膳食提出的…

UG NX二次开发(C#)-参数化修改三维模型中的文字

文章目录 1、前言2、在UG NX中创建一个带文字的三维模型3、创建一个UI界面4、 NXOpen二次开发实现5、测试1、前言 在UG NX中通过表达式不仅能修改尺寸参数、位置参数,也能修改文字,通过设计一个UI 界面,使得文字根据输入值的变化而变化,本文就针对三维模型中得文字来讲一下…

LeakCanary内存泄漏检测框架分析。

一、什么叫内存泄漏、内存溢出&#xff1f; 内存溢出(out of memory)&#xff1a;是指程序在申请内存时&#xff0c;没有足够的内存空间供其使用&#xff0c;出现out of memory&#xff1b;比如申请了一个integer,但给它存了long才能存下的数&#xff0c;那就是内存溢出。 内…

JavaEE——Bean的生命周期

目录 1、实例化Bean 2、设置Bean的属性 3、初始化Bean &#xff08;1&#xff09;、执行通知 &#xff08;2&#xff09;、初始化的前置方法 &#xff08;3&#xff09;、初始化方法 &#xff08;4&#xff09;、执行自定义方法 &#xff08;5&#xff09;、初始化的后置…

js读取接口返回的最快的那一个

promise.race 顾名思义&#xff0c;Promse.race就是赛跑的意思&#xff0c;意思就是说&#xff0c;Promise.race([p1, p2, p3])里面哪个结果获得的快&#xff0c;就返回那个结果&#xff0c;不管结果本身是成功状态还是失败状态。 Promise.race([this.$axios.get("api/on…

UiPath-TTS

UiPath-Text to Speech既TTS应用 缘起原理法一 - Invoke Method法二 - Invoke Code 总结 缘起 不知道大家有没有使用过Excel的Read Cell功能或者智能音箱&#xff0c;实用性因场景而异&#xff0c;但是很好玩。回到RPA应用中&#xff0c;大家想象一下&#xff0c;如果你给自己…

STM32的CAN外设简介

目录 STM32的CAN外设简介 CAN框图剖析 CAN控制内核 工作模式 位时序及波特率 CAN发送邮箱 CAN接收FIFO 验收筛选器&#xff08;重点&#xff09; 整体控制逻辑 STM32的CAN外设简介 STM32的芯片中具有bxCAN控制器 (Basic Extended CAN 基本扩展CAN外设)&#xff0c;它支…

executor.CoarseGrainedExecutorBackend: RECEIVED SIGNAL TERM

Bug现象 spark程序运行正常,但是查看web ui的时候如下图所示: 查看executor logs发现: ERROR executor.CoarseGrainedExecutorBackend: RECEIVED SIGNAL TERM原因分析 首先程序能够正常运行,只是发现某些executor状态为Dead了,说明该executor被移除了,至于为什么会被…

代码随想录算法训练营第二天| 977

977. 有序数组的平方y 思路&#xff0c;原数组是有序的&#xff0c;但是因为负数平方后可能变无序了&#xff0c;因此利用双指针遍历原数组&#xff0c;比较 nums[left]*nums[left]和nums[right]*nums[right]谁更大&#xff0c;然后对新数组赋值 class Solution {public int…

爬虫003_pycharm的安装以及使用_以及python脚本模版设置---python工作笔记021

这里我们用ide,pycharm来编码,看一看如何下载 这里我们下载这个社区办,这个是免费的,个人版是收费的 然后勾选以后 安装以后我们来创建一个项目 这里可以选择python的解释器,选择右边的... 这里我们找到我们自己安装的python解释器

SpringBoot——数据层三组件之间的关系

简单介绍 在之前的文章中&#xff0c;我们介绍了一下SpringBoot中内置的几种数据层的解决方案&#xff0c;在数据层由三部分组成&#xff0c;分别是数据库&#xff0c;持久化技术以及数据源&#xff0c;但是我今天写着写着&#xff0c;突然就想不起来这三部分到底是干什么的了…