生命周期

Misaka10032生命周期大约 3 分钟

React 组件中包含一系列钩子函数(生命周期回调函数),会在特定的时刻调用

我们在定义组件时,会在特定的生命周期回调函数中,做特定的工作

生命周期流程(旧)

简述

React 生命周期可以分成三个阶段:

  1. 挂载阶段:组件状态数据的初始化及初始化渲染
  2. 运行阶段:和用户交互,改变状态并重绘(最长阶段)
  3. 卸载阶段:组件使用完毕后,或者不需要存在于页面中,那么将组件移除,执行销毁(需注意内存泄漏问题)

以类式组件的创建流程为例:

  1. 执行ReactDOM.render
  2. 解析组件标签,找到组件
  3. 发现组件是类定义组件,new 该类实例,通过该实例调用原型上的 render 方法
  4. 将 render 返回的虚拟 DOM 转换为真实 DOM,随后呈现在页面中

render 调用的时机:初始化渲染、状态更新之后

旧生命周期流程图

React旧生命周期流程图
React旧生命周期流程图

流程分析

初始化阶段:ReactDOM.render()触发初次渲染

  1. constructor
  2. componentWillMount
  3. render
  4. componentDidMount

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

更新阶段:组件setState()或父组件 render 触发

  1. componentWillReceiveProps(初始化时不触发,父组件没有更新不触发)
  2. shouldComponentUpdate(setState 时触发)
  3. componentWillUpdate(forceUpdate)
  4. render
  5. componentDidUpdate

卸载阶段:由ReactDOM.unmountComponentAtNode()触发

  1. componentWillUnmount

componentWillUnmount 为常用钩子函数,一般在这个钩子中做一些收尾的事,如:关闭定时器、取消订阅消息

生命周期流程(新)

简述

新生命周期不是对旧生命周期的颠覆,而是合理地优化更新

新的生命周期没有 componentWillMount componentWillReceiveProps componentWillUpdate 钩子函数,以避免异步渲染可能存在的问题

上述三个旧版本生命周期函数在 18.0.X 版本需要在函数名前面添加 UNSAFE_ (UNSAFE_componentWillMount() {})才能工作。

新生命周期增加了一些新的钩子函数

新生命周期流程图

React新生命周期流程图
React新生命周期流程图

流程分析

初始化阶段:ReactDOM.render()触发初次渲染

  1. constructor
  2. getDerivedStateFromProps
  3. render
  4. componentDidMount

componentDidMount 仍是常用钩子函数

更新阶段:组件setState()或父组件 render 触发

  1. getDerivedStateFromProps
  2. shouldComponentUpdate
  3. render
  4. getSnapshotBeforeUpdate
  5. componentDidUpdate

卸载阶段:由ReactDOM.unmountComponentAtNode()触发

  1. componentWillUnmount

componentWillUnmount 仍是常用钩子函数

父子附件渲染顺序

组件渲染的顺序依赖于深度优先原则

父组件第一次渲染:

父 willMount -> 父 render [ 子 willMount -> 子 render -> 子 didMount ] -> 父 didMount

父组件更新:

父 getDerivedStateFromProps -> 父 shouldUpdate -> 父 render -> [ 子父 getDerivedStateFromProps -> 子 shouldUpdate -> 子 render -> 子 didUpdate ] -> 父 didUpdate

特殊情况:我们可以在子组件内部优化处理,验证传递的属性值有没有变化,如果没有变化则禁止更新(memo)

父组件释放:

父 willUnMount -> 父释放中 -> [ 子 willUnMount -> 子释放 ] -> 父释放

重要的钩子

  1. render:初始化渲染或更新渲染调用

  2. componentDidMount:开启监听, 发送 ajax 请求

  3. componentWillUnmount:做一些收尾工作, 如: 清理定时器