目录

  • 前言
  • 一、React 实例的生命周期及其与 Hooks 的映射
    • 1、旧的生命周期图
    • 2、新的生命周期图
    • 3、新旧生命周期及其与 Hooks 的映射表
  • 二、部分生命周期详解
    • 1、getDerivedStateFromProps
    • 2、getSnapshotBeforeUpdate
  • 三、function 组件使用 Hooks 模拟生命周期

前言

在 React 中 class 组件建议使用 “组件的生命周期”,function 组件建议使用 Hooks

对于 class 组件而言,以 React v16.3 为分界线,之前的是“旧的生命周期”,之后的是“新的生命周期”。

一、React 实例的生命周期及其与 Hooks 的映射

1、旧的生命周期图

2、新的生命周期图

React 官方提供了新的生命周期图谱可供查阅。查阅时,勾选上“展示不常用的生命周期”选项,便可以看到完整的 React 组件生命周期。

3、新旧生命周期及其与 Hooks 的映射表

执行阶段 class 组件的生命周期 function 组件中 Hooks 模拟的生命周期
旧的生命周期 新的生命周期 描述 function 组件的 Hooks 描述
创建 componentWillMount(v17 起弃用) 或 UNSAFE_componentWillMount - 数据初始化时执行。只执行一次。

  • 可以初始化 state;
  • 可以获取同步的数据,不能获取异步数据。
X
- constructor constructor 是 ES6 class 语法里的构造函数。只执行一次。

  • 可以初始化 state。
useState
- static getDerivedStateFromProps 在组件实例化之后调用。

  • 在挂载阶段用来代替componentWillMount。
useEffect 手动对比 props, 配合 useState 里面 update 函数
render 同旧的 初次渲染之前调用。每次渲染 DOM 都会触发。

  • 在初次渲染阶段,会生成一个虚拟 DOM 树。
函数本身
componentDidMount 同旧的 数据成功挂载到 DOM 上后执行。

  • 可以获取同步数据、异步数据(React 可确保在用户看到更新的 UI 之前,刷新在 componentDidMount 期间发生的任何 setState 调用)。
useEffect 第二个参数为:`[]`
更新 componentWillReceiveProps(v17 起弃用) 或 UNSAFE_componentWillReceiveProps - 在组件重新渲染之前调用。

  • 仅在父组件重新渲染时会触发此钩子。
X
- static getDerivedStateFromProps 在组件重新渲染之前调用。

  • 在组件更新阶段配合 componentDidUpdate,可以覆盖过时的 componentWillReceiveProps 的所有用法。
  • props 变化时会调用该方法,来更新 state(父组件重新渲染)。
  • state 变化时也会调用该方法(比如使用 setState 修改 state)。
useEffect 手动对比 props, 配合 useState 里面 update 函数
shouldComponentUpdate 同旧的 更新之前调用。在更新阶段执行一次。控制组件的重新渲染。

  • 在更新阶段, React 默认会更新所有的组件。可以在此钩子中设置当前组件不参与此次更新(性能提升)。
React.memo React.memo 等效于 PureComponent,它只浅比较 props。这里也可以使用 useMemo 优化每一个节点。
componentWillUpdate(v17 起弃用) 或 UNSAFE_componentWillUpdate - 在组件重新渲染之前调用。

  • 可以同步更改 state 和 props 的数据,不要异步操作。
  • 可能在一次更新中被多次调用。
X
render 同旧的 更新之前调用。每次渲染 DOM 都会触发。

  • 在更新阶段,React 会通过其 diff 算法比较更新前后的新旧 DOM 树,然后,找到最小差异的 DOM 节点,重新渲染。
函数本身
- getSnapshotBeforeUpdate 更新真实 DOM 之前调用。此时 state 已更新。

  • 与 componentDidUpdate 一起,这个新的生命周期涵盖过时的 componentWillUpdate 的所有用例。
  • 此生命周期的返回值将作为第三个参数传递给 componentDidUpdate。(通常不需要,但在重新渲染过程中手动保留滚动位置等情况下非常有用。)
  • 可以在此钩子中获取更新前的 DOM。
componentDidUpdate 同旧的 更新结束后执行。

  • 支持同步更新、异步更新(React 可确保在用户看到更新的 UI 之前,刷新在 componentDidUpdate 期间发生的任何 setState 调用)。
  • 保证每次更新只调用一次。
useEffect 配合 useRef
卸载 componentWillUnmount 同旧的 组件卸载之前调用。

  • 只有调用了 componentDidMount 之后,React 才能保证稍后调用 componentWillUnmount 进行清理。
  • 组件将被卸载,组件中的数据将被销毁。
useEffect 里面返回的函数

【拓展】过时的生命周期方法

React v16.3 为不安全的生命周期引入别名,建议尽量不要使用这些不安全的生命周期:

  • componentWillMount 被命名为 UNSAFE_componentWillMount;
  • componentWillReceiveProps 被命名为 UNSAFE_componentWillReceiveProps;
  • componentWillUpdate 被命名为 UNSAFE_componentWillUpdate。

在 v16.3 以后至 v17.0 之前的所有版本中,“旧的名称和新的别名”都可以使用,但是旧的名称在开发模式下会有警告。在 v17.0 中,“旧的名称”被弃用了,“新的别名”仍然可以使用。

【注意】UNSAFE_componentWillReceiveProps 和 getDerivedStateFromProps
旧的 UNSAFE_componentWillReceiveProps 和新的 getDerivedStateFromProps 方法都会增加组件的复杂性。这经常会导致 bug。考虑使用 派生 state 的简单替代方法 让组件可预测且可维护。比如:

  • 在旧的 UNSAFE_componentWillReceiveProps 钩子和新的 getDerivedStateFromProps 钩子里,建议直接使用 props 里的属性,不要在当前组件中用 state 去承接一下,否则可能会造成:“父组件传来的 props 更新了,但子组件依然没有变化” 的问题。除非你只是想将 props 里的某个属性作为当前组件里需要使用的一个默认值。那之后的值就和 prop 没关系了。

二、部分生命周期详解

1、getDerivedStateFromProps

在旧版本中,componentWillReceiveProps() 方法用于:在接受父组件改变后的props需要重新渲染组件时,对比 nextProps 和 this.props,将 nextProps 的 state 为当前组件的 state,从而重新渲染组件。不过,这样会破坏 state 数据的单一数据源,导致组件状态变得不可预测,从而增加了组件重绘的次数。

在新版本中,官方用 getDerivedStateFromProps(nextProps, prevState) 代替 componentWillReceiveProps(nextProps)。

getDerivedStateFromProps 钩子函数:

  • 无法直接访问 this.props,强制让开发者去比较 nextProps 与 prevState 中的值,以确保使用 getDerivedStateFromProps() 这个钩子函数时,就是在根据当前的 props 来更新组件的 state,而不是去做其他一些让组件自身状态变得更加不可预测的事情。

非必须应尽可能少的使用该钩子函数——基于该钩子函数的派生状态会导致代码冗余,并使组件难以维护。 确保你已熟悉这些简单的替代方案:

  • 如果你需要执行副作用(例如,数据提取或动画)以响应 props 中的更改,请改用 componentDidUpdate。
  • 如果只想在 prop 更改时重新计算某些数据,请使用 memoization helper 代替。
  • 如果你想在 prop 更改时“重置”某些 state,请考虑使组件完全受控或使用 key 使组件完全不受控 代替。

2、getSnapshotBeforeUpdate

在旧版本中,componentWillUpdate() 方法用于:在组件更新前,读取当前某个 DOM 元素的状态,并在 componentDidUpdate 中进行相应的处理。在 React 开启异步渲染模式后,在 render 阶段读取到的 DOM 元素状态并不总是和 commit 阶段相同,这就导致在 componentDidUpdate 中使用 componentWillUpdate 中读取到的 DOM 元素状态是不安全的,因为这时的值很有可能已经失效了。

在新版本中,官方用 getSnapshotBeforeUpdate(prevProps, prevState) 替代 componentWillUpdate(nextProps, nextState) 。

getSnapshotBeforeUpdate() 方法用于:在最近一次渲染输出(提交到 DOM 节点)之前调用。也就是说,在 getSnapshotBeforeUpdate() 方法中,读取到的 DOM 元素状态是可以保证与 componentDidUpdate 中一致的。另外,getSnapshotBeforeUpdate() 钩子函数返回的任何值都将作为参数传递给 componentDidUpdate() 方法。

getSnapshotBeforeUpdate 并不常用,但它可能出现在 UI 处理中,如需要以特殊方式处理滚动位置的聊天线程等。

三、function 组件使用 Hooks 模拟生命周期

React 之 function 组件里使用 Hooks

【参考文章】
React Hooks 介绍及与传统 class 组件的生命周期函数对比
Hooks 与 React 生命周期的关系

React 组件的生命周期相关推荐

  1. React 初探 [五] React 组件的生命周期

    说起生命周期,最先接触的是Andorid 开发中 Activity 和 Fragment 的生命周期,再者是Vue 组件,那么今天要梳理的是React 组件的生命周期,可见对生命周期的理解和掌握对组件 ...

  2. React组件的生命周期

    react组件的生命周期 文章目录 react组件的生命周期 总览 挂载时 更新时 卸载时 被移除的生命周期 总览 React的生命周期大体可以分为三个部分,一,挂载阶段:二更新阶段三,卸载阶段 挂载 ...

  3. React 组件的生命周期详解

    2019独角兽企业重金招聘Python工程师标准>>> 概念:在组建的创建.到加载到页面上运行以及组件被销毁的过程中,总是伴随的各种各样的事件,这些在组件特定时期,出触发的事件就叫做 ...

  4. react学习笔记(4)组件的生命周期(运行阶段和销毁阶段)以及事件处理函数

    1.组件的生命周期 接着(2)中的组件生命周期 1.运行阶段 运行阶段有5个步骤: componentWillReceiveProps: 父组件修改属性触发,可以修改新属性,修改状态. shouldC ...

  5. Android之React Native 中组件的生命周期

    React Native 中组件的生命周期 概述 就像 Android 开发中的 View 一样,React Native(RN) 中的组件也有生命周期(Lifecycle).所谓生命周期,就是一个对 ...

  6. React简介、虚拟DOM、Diff算法、创建React项目、JSX语法、组件、组件声明方式、组件传值props和state、组件的生命周期

    React简介: 前面只是简单介绍移动APP开发,后面还会继续深入介绍移动app开发:其中想要用ReactNative开发出更出色的应用,那么就得学好React,下面将介绍React: React 是 ...

  7. native react 更新机制_React Native - 组件的生命周期详解(附:各阶段调用的方法)...

    一个 React Native 组件从它被 React Native框架加载,到最终被 React Native 框架卸载,会经历一个完整的生命周期. 在这个生命周期中,我们可以定义一些生命周期函数, ...

  8. React 深入系列4:组件的生命周期

    文:徐超,<React进阶之路>作者 授权发布,转载请注明作者及出处 React 深入系列4:组件的生命周期 React 深入系列,深入讲解了React中的重点概念.特性和模式等,旨在帮助 ...

  9. 03 为什么 React 16 要更改组件的生命周期?(下)

    通过对上一个课时的学习,你已经对 React 15 的生命周期有了系统的掌握和理解.本课时,我将在此基础上,对 React 16 以来的生命周期进行剖析.在理解"是什么"的基础上, ...

最新文章

  1. 牛逼哄哄的 Lambda 表达式,简洁优雅就是生产力!
  2. 视频直播技术详解(3)编码和封装
  3. 数据库中范式的理解1NF、2NF、3NF
  4. 代码重构的实战经验和那些坑
  5. 基础理论:啥是分布函数CDF、啥叫联合分布?
  6. 趣谈设计模式 | 观察者模式(Observer) :消息的发布与订阅
  7. vos限制客户呼出时间
  8. 部署:持续集成(CI)与持续交付(CD)——《微服务设计》读书笔记
  9. PHP5.3x被弃用的函数及代替方法
  10. Java学习系列(十六)Java面向对象之基于TCP协议的网络通信
  11. 【python+selenium】保留浏览器的自定义设置,不恢复浏览器默认设置
  12. ise 14.7 XST.exe停止工作
  13. 使用OLED屏显示汉字
  14. Python统计字符串中出现次数最多的人名
  15. 点评美国名校的(EE)和(CS)
  16. 计算机工作日志小学,班主任工作日志记录 小学班主任工作计划合集
  17. 百味融汇的火锅宴,品一品别样热辣的鲲鹏生态
  18. 网页上编辑的内容因为网页误关被删了,怎么恢复
  19. 洛谷 P1423 小玉在游泳 AC
  20. html拖动控件详解

热门文章

  1. sklearn中Logistics Regression的coef_和intercept_的具体意义
  2. Java并发编程笔记之 CountDownLatch闭锁的源码分析
  3. Mac连上WIFI但是无法上网的3种解决方案
  4. iOS开发之百度地图的简单集成——标注POI检索
  5. IDEA设置注释模板最佳实践
  6. 基于vue,js的简单pc 音乐播放器
  7. 华为mate10手机听筒测试软件,【华为Mate10评测】通讯:终于可以一边电话一边游戏_华为 Mate 10保时捷版_手机评测-中关村在线...
  8. hazptr folly
  9. 程序员必备的几个图形制作工具
  10. 学顶教育:2023年一级建造师报考条件如下