React 生命周期

1,073 阅读3分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动

当讨论React组件生命周期,基本是围绕着类组件进行讨论的,因为目前有些观点认为:当函数组件引入Hooks之后,函数组件也具备了生命周期

下面一起看一看React16.3之后类组件的生命周期的三个阶段:挂载、更新和卸载

挂载阶段

挂载过程在组件的一生中仅会发生一次,在这个过程中,组件被初始化,然后会被渲染到真实 DOM 里,完成“首次渲染”

constructor

constructor 是类通用的构造函数,该方法仅仅在挂载阶段的时候被调用一次,常用于初始化 state 与绑定函数

import React from 'react'

class Demo extends React.Component {
  constructor(props) {
    super(props);
    this.state = { name: "nordon" };
    this.clickHandler = this.clickHandler.bind(this);
  }
}

随着技术的发展,目前已经渐渐很少有人还在constructor中这么做了

移除constructor原因:

  1. constructor是class中的初始化函数,和React生命周期并没太直接的关系
  2. constructor中并不适合处理初始化以外的逻辑
  3. 代码会变得整洁
import React from 'react'

class Demo extends React.Component {
  state = { name: "nordon" };

  clickHandler = () => {}
}

getDerivedStateFromProps

React 16.3 生命周期 getDerivedStateFromProps,其用法如下

static getDerivedStateFromProps(props, state)

其作用是使组件在 props 变化时派生 state,触发时机:

  1. 当 props 被传入时
  2. state 发生变化时;
  3. forceUpdate 被调用时。

render

render 函数返回的 JSX 结构,用于描述具体的渲染内容

由于其是一个纯函数,因此千万不要在里面产生具有副作用的操作,比如调用setState、绑定事件等

componentDidMount

在浏览器中,触发componentDidMount时,我们是可认为界面已经绘制完成,主要用于组件加载完成时处理一些事情,比如发起请求

更新阶段

getDerivedStateFromProps

同挂载阶段

shouldComponentUpdate

该方法通过返回 true 或者 false 来确定是否需要触发新的渲染。因为渲染触发最后一道关卡,所以也是性能优化的必争之地。通过添加判断条件来阻止不必要的渲染。

shouldComponentUpdate(nextProps, nextState) {
  // 浅比较仅比较值与引用,并不会对 Object 中的每一项值进行比较
  if (shadowEqual(nextProps, this.props) || shadowEqual(nextState, this.state) ) {
    return true
  }
  return false
}

render

同挂载阶段

getSnapshotBeforeUpdate

与 componentDidUpdate 一起,这个新的生命周期涵盖过时componentWillReceiveProps 的所有用例。

getSnapshotBeforeUpdate 方法是配合 React 新的异步渲染的机制,在 redner前被调用,返回值将作为 componentDidUpdate 的第三个参数。

getSnapshotBeforeUpdate(prevProps, prevState) {
  // todo ...
}

componentDidUpdate

getSnapshotBeforeUpdate返回的值回作为第三个参数传递

componentDidUpdate(prevProps, prevState, valueFromSnapshot) {
  // 从 getSnapshotBeforeUpdate 获取到的值是: valueFromSnapshot
}

卸载阶段

componentWillUnmount

该函数主要用于执行清理工作。一个比较常见的 Bug 就是忘记在 componentWillUnmount 中取消定时器,导致定时操作依然在组件销毁后不停地执行。所以一定要在该阶段解除事件绑定,取消定时器