当前位置: 首页 > news >正文

详解react生命周期和在父子组件中的执行顺序

前言

react 生命周期指的是组件从创建到卸载的整个过程,每个过程都有对应的钩子函数会被调用,它主要有以下几个阶段:

  • 挂载阶段 :组件实例被创建和插入 DOM 树的过程
  • 更新阶段 :组件被重新渲染的过程
  • 卸载阶段 :组件从 DOM 树中被删除的过程

下文分别从上述三个阶段解读react的生命周期

旧版生命周期

在这里插入图片描述

  • 挂载阶段:componentWillMount - render - componentDidMount
  • 更新阶段:componentWillReceiveProps - shouldComponentUpdate - componentWillUpdate - render - componentDidUpdate
  • 卸载阶段:componentWillUnmount

挂载阶段

componentWillMount

componentWillMount发生在render之前,此时还没有挂载DOM,有可能会被执行多次

componentDidMount

常用的钩子,在组件挂载成功之后调用,该过程组件已经成功挂载到了真实 DOM 上。

一般在这个钩子中做一些初始化的事,例如:开启定时器、发送网络请求、订阅消息

componentDidMount(){
  fetch('https://api.github.com/users').then(res=>res.json()).then(users=>{
    console.log(users);
    this.setState({users});
  });
}

更新阶段

componentWillReceiveProps(newProps)

props发生改变(父组件重新render或者更新props)时调用,这个钩子提供对 props 的监听,在 props 发生改变后,相应改变组件的一些 state。在这个方法中改变 state 不会二次渲染,而是直接合并 state。

shouldComponentUpdate(nextProps, nextState)

这个钩子相当于一个阀门,返回一个布尔值,决定是否更新组件。

由于 react 父组件更新,必然会导致子组件更新,因此我们可以在子组件中通过手动对比 propsnextPropsstatenextState 来确定是否需要重新渲染子组件,如果需要则返回true,不需要则返回 false。该函数默认返回 true

componentWillUpdate

组件更新前调用的钩子

componentDidUpdate

组件更新完成后调用的钩子

  • 因为组件已经重新渲染了所以这里可以对组件中的 DOM 进行操作;
  • 在比较了 this.propsnextProps 的前提下可以发送网络请求。
componentDidUpdate(prevProps, prevState, snapshot) {
	if (this.props.userID !== prevProps.userID) {
    this.fetchData(this.props.userID);
  }
}

卸载阶段

componentWillUnmount

卸载阶段唯一的生命周期钩子,通常在这里处理一些善后工作,例如关闭定时器、取消监听等等

旧版生命周期执行流

在这里插入图片描述

新版生命周期

react 打算在17版本推出新的 Async Rendering(异步渲染),提出一种可被打断的生命周期,而可以被打断的阶段正是实际 dom 挂载之前的虚拟 dom 构建阶段,也就是要被去掉的三个生命周期。

  • 废弃了三个生命周期:componentWillMount,componentWillReceiveProps,componentWillUpdate
  • 新增了两个生命周期:static getDerivedStateFromProps(nextProps, prevState)getSnapshotBeforeUpdate(prevProps, prevState)

在这里插入图片描述

  • 挂载阶段:getDerivedStateFromProps - render - componentDidMount
  • 更新阶段:getDerivedStateFromProps - shouldComponentUpdate - render - getSnapShotBeforeUpdate - componentDidUpdate
  • 卸载阶段:componentWillUnmount

static getDerivedStateFromProps(nextProps, prevState)

该生命周期在 render方法之前调用,在初始化和后续更新都会被调用

它接收两个参数,一个是传进来的 nextProps 和之前的 prevState。他应该返回一个对象来更新 state。如果返回 null 则不更新任何内容。

这个生命周期主要为我们提供了一个可以在组件实例化或 propsstate 发生变化后根据 props 修改 state 的一个时机。

getSnapshotBeforeUpdate(prevProps, prevState)

在更新阶段 render 后挂载到真实 DOM 前进行的操作,它使得组件能在发生更改之前从 DOM 中捕获一些信息。此组件返回的任何值将作为 componentDidUpdate 的第三个参数。

  getSnapshotBeforeUpdate(prevProps, prevState){
    return "getSnapshotBeforeUpdate";
  }

  // 组件更新成功钩子
  componentDidUpdate(prevProps, prevState, snapshot) {
    console.log(snapshot); // "getSnapshotBeforeUpdate"
  }

父子组件生命周期执行顺序

父子组件初始化

  • 父组件 constructor
  • 父组件 getDerivedStateFromProps
  • 父组件 render
  • 子组件 constructor
  • 子组件 getDerivedStateFromProps
  • 子组件 render
  • 子组件 componentDidMount
  • 父组件 componentDidMount

子组件修改自身state

  • 子组件 getDerivedStateFromProps
  • 子组件 shouldComponentUpdate
  • 子组件 render
  • 子组件 getSnapShotBeforeUpdate
  • 子组件 componentDidUpdate

父组件修改props

  • 父组件 getDerivedStateFromProps
  • 父组件 shouldComponentUpdate
  • 父组件 render
  • 子组件 getDerivedStateFromProps
  • 子组件 shouldComponentUpdate
  • 子组件 render
  • 子组件 getSnapShotBeforeUpdate
  • 父组件 getSnapShotBeforeUpdate
  • 子组件 componentDidUpdate
  • 父组件 componentDidUpdate

卸载子组件

  • 父组件 getDerivedStateFromProps
  • 父组件 shouldComponentUpdate
  • 父组件 render
  • 父组件 getSnapShotBeforeUpdate
  • 子组件 componentWillUnmount
  • 父组件 componentDidUpdate

参考文档

React 框架生命周期(类组件与函数组件)

深入详解React生命周期

相关文章:

  • 2022年山东省安全员C证复训题库模拟考试平台操作
  • 《算法导论》第11章-散列表 11.1-直接寻址表 11.2 散列表
  • 归并排序算法
  • DNSPod十问百果园焦岳:为什么开水果店是一门高科技生意?
  • 《nginx》三、nginx负载均衡
  • 操作系统——程序地址空间
  • JavaScript-操作表单和前端加密
  • 使用disruptor队列实现本地异步消费
  • 在Windows中自动压缩备份文件和目录的脚本
  • 猿创征文|Java计算【生日工具类】看这篇就够了
  • 网络-电脑网络突然变成球形, 网络不可用
  • 848. 有向图的拓扑序列(BFS应用)
  • 物联网开发笔记(8)- 使用Wokwi仿真ESP32开发板实现模数转换和脉宽调制
  • 古怪的Lucene中文分词方案 —— CJKAnalyzer
  • SPDK vhost-user结合SPDK NVMe-oF RDMA性能调优
  • Linux CTF 逆向入门
  • MQ框架的比较
  • nginx 负载服务器优化
  • Spring声明式事务管理之一:五大属性分析
  • vuex 学习笔记 01
  • 翻译 | 老司机带你秒懂内存管理 - 第一部(共三部)
  • 给自己的博客网站加上酷炫的初音未来音乐游戏?
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 看完九篇字体系列的文章,你还觉得我是在说字体?
  • 如何设计一个比特币钱包服务
  • 我与Jetbrains的这些年
  • 用Python写一份独特的元宵节祝福
  • 原生js练习题---第五课
  • ​ 全球云科技基础设施:亚马逊云科技的海外服务器网络如何演进
  • ###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯
  • #NOIP 2014# day.2 T2 寻找道路
  • #多叉树深度遍历_结合深度学习的视频编码方法--帧内预测
  • #我与Java虚拟机的故事#连载10: 如何在阿里、腾讯、百度、及字节跳动等公司面试中脱颖而出...
  • (3)nginx 配置(nginx.conf)
  • (Demo分享)利用原生JavaScript-随机数-实现做一个烟花案例
  • (二十四)Flask之flask-session组件
  • (十五)使用Nexus创建Maven私服
  • (万字长文)Spring的核心知识尽揽其中
  • (一)eclipse Dynamic web project 工程目录以及文件路径问题
  • (转)Java socket中关闭IO流后,发生什么事?(以关闭输出流为例) .
  • (转)程序员疫苗:代码注入
  • (转)树状数组
  • ***详解账号泄露:全球约1亿用户已泄露
  • .NET CORE Aws S3 使用
  • .net core 实现redis分片_基于 Redis 的分布式任务调度框架 earth-frost
  • .NET Core实战项目之CMS 第一章 入门篇-开篇及总体规划
  • .net 设置默认首页
  • .net下简单快捷的数值高低位切换
  • .py文件应该怎样打开?
  • [ 2222 ]http://e.eqxiu.com/s/wJMf15Ku
  • [<事务专题>]
  • [20150629]简单的加密连接.txt
  • [ai笔记9] openAI Sora技术文档引用文献汇总
  • [Android]Android P(9) WIFI学习笔记 - 扫描 (1)
  • [BUG] Authentication Error