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 组件中唯一必须实现的方法,用于渲染 dom,render() 方法必须返回 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 生命周期,不会再触发别的生命周期。

参考