Skip to content
大纲

React lifecycle

生命周期参见下图

生命周期

  • 创建挂载
    • constructor 🔥
    • static getDerivedStateFromProps(nextProps, state)
    • render 🔥
    • componentDidMount 🔥
  • 更新
    • static getDerivedStateFromProps(nextProps, state)
    • shouldComponentUpdate 🔥
    • render
    • getSnapshotBeforeUpdate
    • componentDidUpdate 🔥
  • 卸载
    • componentWillUnmount 🔥
  • 异常捕获
    • static getDerivedStateFromError(error)
    • componentDidCatch(error, errorInfo)

React 从 v16.3 开始废弃 componentWillMount componentWillReceiveProps componentWillUpdate 三个钩子函数

详解生命周期

constructor()

  • super 的作用:将父类的 this 对象继承给子类 (MDN 参考)
  • 如果不初始化 state 或不进行方法绑定,则不需要写 constructor(),只需要设置 this.state 即可
  • 不能在 constructor() 构造函数内部调用 this.setState(), 因为此时第一次 render() 还未执行,也就意味 DOM 节点还未挂载

static getDerivedStateFromProps(nextProps, prevState)

根据 nextProps 和 prevState 计算出预期的状态改变,返回结果(一个对象)会被送给 setState 更新 state,返回 null 则不更新 state

注意:getDerivedStateFromProps 是一个静态函数,不能使用 this,应该是一个纯函数,也就是只能作一些无副作用的操作

使用场景,这个方法就是提供了一个机会,可以根据新 props旧 state 来调整新的 state

为什么要这样做?请移步 Morgan 大佬 - 知乎

render()

class 组件中唯一必须实现的方法,用于渲染 domrender() 方法必须返回 reactDOM

不要在 render 里面 setState, 否则会触发死循环导致内存崩溃

componentDidMount()

componentDidMount() 再组件挂在后(插入 DOM 树后)立即调用,componentDidMount() 是发送网络请求、启用事件监听方法的好时机,并且可以在此钩子函数里直接调用 setState

shouldComponentUpdate(nextProps, nextState)

shouldComponentUpdate() 在组件更新之前调用,可以控制组件是否进行更新,返回 true 时组件更新,返回 false 则不更新

可以根据更新前后的 props 或 state 来比较加一些限制条件,决定是否更新,进行性能优化

注意

不建议在 shouldComponentUpdate() 中进行深层比较或实用JSON.stringify()。这样非常影响效率,且会损害性能。

不要 shouldComponentUpdate() 中调用 setState(),否则会导致无限循环调用更新、渲染,直至浏览器内存崩溃

可以使用内置 PureComponent 组件替代

getSnapshotBeforeUpdate(prevProps, prevState)

在最近一次的渲染输出被提交之前调用。也就是说在 render 之后,即将对组件进行挂载时调用。

它可以使组件在 DOM 真正更新之前捕获一些信息(例如滚动位置),此生命周期返回的任何值都会作为参数传递给 componentDidUpdate() 第三个参数。如果不需要传递任何值,那么请返回 null

componentDidUpdate(prevProps, prevState, snapshot)

会在更新后被立即调用。首次渲染不会执行。

可以进行前后 props 的比较进行条件语句的限制,来进行 setState,否则会导致死循环。

componentWillUnmount()

在组件即将被卸载或销毁时进行调用。

此生命周期是取消网络请求、移除监听事件、清理 DOM 元素、清理定时器等操作的好时机

生命周期执行顺序

  • 子组件自身状态改变,不会对父组件产生副作用的情况下,父组件不会进行更新(无生命周期触发)
  • 父组件中状态发生变化(包括子组件的挂载以及卸载)时,会触发自身对应的生命周期以及子组件的更新
    • render 以及 render 之前的生命周期,则父组件先执行
    • render 以及 render 之后的生命周期,则子组件先执行,并且是与父组件交替执行

当子组件进行卸载时,只会执行自身的 componentWillUnmount 生命周期,不会再触发别的生命周期。

参考