React v16生命周期

生命周期是框架为我们提供的用于了解程序当前运行阶段的一个钩子。

旧生命周期

3284159097-5bbb08d17db33_articlex.png

挂载阶段(Mounting)

  • constructor()

    加载的时候调用一次,用于初始化state

  • getDefaultProps()

    设置默认的props,也可以用dufaultProps设置组件的默认属性

  • getInitialState()

    初始化state,可以直接在constructor中定义this.state

  • componentWillMount()

    组件将要挂载时调用,整个生命周期调用一次

  • render()

    react最重要的步骤,创建虚拟dom,进行diff算法,更新dom树都在此进行

  • componentDidMount()

    组件渲染之后调用,http请求一般在此时进行

更新阶段(Updating)

  • componentWillReceivePorps(nextProps)

    组件加载时不调用,当组件的props更新后调用,参数nextProps为新传入的props

  • shouldComponentUpdate(nextProps, nextState)

    组件接收到新的props或state时调用,参数nextProps为新传入的props,state为新的state。可通过判断nextProps,nextState和this.props,this.state进行选择性rerender,return true代表需要触发render更新当前组件,return false代表不需要触发render

  • componentWillUpdata(nextProps, nextState)

    组件将要更新时调用

  • render()

    组件rerender

  • componentDidUpdate()

    组件完成更新时调用

卸载阶段(Unmounting)

  • componentWillUnmount()

    组件将要卸载时调用

在React V16之前的版本中,如果你拥有一个很复杂的复合组件,然后改动了最上层组件的 state,那么调用栈可能会很长。

调用栈过长,再加上中间进行了复杂的操作,就可能导致长时间阻塞主线程,带来不好的用户体验。所以为了解决这个问题,React V16引入了Fiber机制。

Fiber 本质上是一个虚拟的堆栈帧,新的调度器会按照优先级自由调度这些帧,从而将之前的同步渲染改成了异步渲染,在不影响体验的情况下去分段计算更新。

对于如何区别优先级,React 有自己的一套逻辑。对于动画这种实时性很高的东西,也就是 16 ms 必须渲染一次保证不卡顿的情况下,React 会每 16 ms(以内) 暂停一下更新,返回来继续渲染动画。

对于异步渲染,现在渲染有两个阶段:reconciliationcommit 。前者过程是可以打断的,后者不能暂停,会一直更新界面直到完成。

Reconciliation 阶段

  • componentWillMount
  • componentWillReceiveProps
  • shouldComponentUpdate
  • componentWillUpdate

Commit阶段

  • componentDidMount
  • componentDidUpdate
  • componentWillUnmount

因为 Reconciliation 阶段是可以被打断的,所以 Reconciliation 阶段会执行的生命周期函数就可能会出现调用多次的情况,从而引起 Bug。由此对于 Reconciliation 阶段调用的几个函数,除了 shouldComponentUpdate 以外,其他都应该避免去使用,并且 V16 中也引入了新的 API 来解决这个问题。

getDerivedStateFromProps 用于替换 componentWillReceiveProps ,该函数会在初始化和 update 时被调用。

getSnapshotBeforeUpdate 用于替换 componentWillUpdate ,该函数会在 update 后 DOM 更新前被调用,用于读取最新的 DOM 数据。

新生命周期

挂载阶段(Mounting)

  • constructor()

    同之前

  • static getDerivedStateFromProps(props, state)

    静态方法,组件每次被rerender的时候,包括在组件构建之后(虚拟dom之后,实际dom挂载之前),每次获取新的props或state之后;每次接收新的props之后都会返回一个对象作为新的state,返回null则说明不需要更新state;配合componentDidUpdate,可以覆盖componentWillReceiveProps的所有用法

  • render()

    同之前

  • componentDidMount()

同之前

更新阶段(Updating)

  • static getDerivedStateFromProps(props, state)

    静态方法,组件每次被rerender的时候,包括在组件构建之后(虚拟dom之后,实际dom挂载之前),每次获取新的props或state之后;每次接收新的props之后都会返回一个对象作为新的state,返回null则说明不需要更新state;配合componentDidUpdate,可以覆盖componentWillReceiveProps的所有用法

  • shouldComponentUpdate(nextProps, nextState)

    同之前

  • render()

    同之前

  • getSnapshotBeforeUpdate(prevProps, prevState)

    被调用于render之后,可以读取但无法使用dom的时候。它使您的组件可以在可能更改之前从DOM捕获一些信息(例如滚动位置)。返回一个值作为componentDidUpdate的第三个参数。

  • componentDidUpdate(prevProps, prevState, snapshot)

    组件更新完成后调用。第三个参数为getSnapshotBeforeUpdate的返回值。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • React 16 生命周期 React 16.3 新增的生命周期方法 逐渐废弃的生命周期方法: 一般将生命周期分成...
    Allan要做活神仙阅读 592评论 0 0
  • React 生命周期很多人都了解,但通常我们所了解的都是单个组件的生命周期,但针对Hooks 组件、多个关联组件(...
    前端js阅读 7,090评论 3 7
  • 在React更新到V16版本后,我们会发现React新加了一些生命周期并且即将停用一些生命周期,今天我们就来fol...
    龚达耶阅读 1,157评论 0 0
  • 组件的生命周期 React中组件也有生命周期,也就是说也有很多钩子函数供我们使用, 组件的生命周期,我们会分为四个...
    解勾股阅读 762评论 0 0
  • 以前觉得自己接受不了爱情降温的落差 那就应该在最开始的时候不要那么灼热 因为一切总会归于平淡被鸡毛蒜皮和事无巨细淹...
    萱萱_萱阅读 448评论 0 3