React生命周期函数理解

顾名思义:组件的生命周期函数就是贯穿一个组件从出生(挂载)到死亡(卸载)这段时间中 特殊时间点所会触发的函数

一、生命周期执行顺序

(1)、挂载:

  componentWillMount() ——> render() ——> componentDidMount()

(2)、更新

  1、props更新,父级组件重新渲染

  componentWillReceiveProps(nextProps) ——> shouldComponentUpdata(nextProps, nextState) 或

  componentWillReceiveProps(nextProps) ——> shouldComponentUpdata(nextProps, nextState) ——> componentWillUpdate(nextProps, nextState) ——> render() ——> componentDidUpdate(prevProps, prevState)

  2、state更新,自身状态发生改变

  shouldComponentUpdate(nextProps, nextState) 或

  shouldComponentUpdate(nextProps, nextState) ——> componentWillUpdate(nextProps, nextState) ——> render() ——> componentDidUpdate()

(3)、卸载

  componentWillUnmount()

二、生命周期函数使用场景

 (1)componentWillMount()

  组件挂载阶段,render执行前执行。可以根据props进行setState,render会感知到更新后的state,仅会执行一次,不会触发重新渲染。

  这里不建议发送AJAX请求,由于请求是异步的,在接下来的第一次render中,一定获取不到响应数据。

    (2) render()

  该方法创建一个虚拟dom,表示组件的输出。(输出可以应用到react-dom,react-native)

  (3)componentDidMount()

  组件挂载完毕,已经生成真实DOM。

  可以对DOM节点进行操作,设置定时器,发送AJAX请求

  (4)  componentWillReceiveProps(nextProps)

  已挂载组件在接收到新的props时会触发,这里的新的props有点歧义,可以理解为只要父组件重新渲染,子组件就会接收到新的props,从而触发这个方法。

  当props发生变化,组件自身状态需要做出改变,即state做出对应响应时,可以在此方法中执行;

 (5)shouldComponentUpdate(nextProps, nextState)

  接收到新的props或state,判断是否需要发生重新渲染,默认返回true,表示重新渲染

  该方法在首次渲染或者forceUpdate时不会触发

 (6)componentWillUpdate(nextProps, nextState)

  该方法中禁止调用this.setState()方法

  使用该方法做一些更新之前的准备工作

 (7)componentDidUpdate(prevProps, prevState)

   在组件的更新已经同步到dom上立即调用,可以操作更新之后的dom

 (8)componentWillUnmount()

  在组件卸载之前调用,一般进行清除定时器,取消请求或清除在componentDidMount中创建的DOM元素等操作

 

三、React v16.3之后的生命周期

  首先说一下React同步更新导致的性能问题:

  组件更新需要耗费时间,当存在多重组件嵌套时,最顶部的父级组件更新导致下级的组件也要更新时,会占据大量的时间。浏览器的GPU在这段时间内只能进行更新工作,没办法做其他的事情,此时用户也无法与其进行交互,造成浏览器卡顿的现象。

  解决方案:分片更新

  React Fiber将更新过程碎片化,每执行一段更新过程,就把控制权交换给React负责任务协调的模块,看看是否有其他更紧急的任务要做,如果没有就继续更新,如果有紧急任务,就执行紧急任务,执行完毕之后从头开始进行更新任务。

  更新过程:以render为界分为两个阶段,Reconciliation Phase(调和) 和 Commit Phase(重构)

  第一个过程会找出需要更新哪些DOM,该过程可以被打断;

  第二个阶段会把需要更新的DOM进行更新操作,不可打断

  第一阶段可能会执行以下生命周期函数:componentWillMount、componentWillReceiveProps、shouldComponentUpdate、componentWillUpdate

  第二个阶段:componentDidMount、componentDidUpdate、componentWillUnmount

 

  第一阶段的生命周期函数在16.3由于采用分片更新可能会出现调用多次的情况,故废弃了componentWillReceiveProps、componentWillMount、componentWillUpdate,用getDerivedStateFromProps替代,目的在于强制开发者在render之前只做无副作用的操作。而且所作的操作也仅限于根据nextProps和nextState设置state。

  getDerivedStateFromProps(nextProps, nextState)是一个静态函数,内部不能访问this。根据nextProps和nextState计算出预期的状态改变,返回结果会被送给setState

  getSnapshotBeforeUpdate() 在render之后,componentDidUpdate之前执行

故16.3之后的挂载、更新和卸载执行顺序为:

挂载:getDerivedStateFromProps(nextProps, nextState) ——> render() ——> componentDidMount()

更新:

  props更新:getDerivedStateFromProps(nextProps, nextState) ——> shouldComponentUpdate(nextProps, nextState)——> render——> getSnapshotBeforeUpdate(prevProps, prevState)——> componentDidUpdate(prevProps, prevState, snapShot);

  state更新:shouldComponentUpdate(nextProps, nextState)——> render——> getSnapshotBeforeUpdate(prevProps, prevState)——> componentDidUpdate(prevProps, prevState, snapShot);

卸载: componentWillUnmount()

引用:https://moeover.com/2017/01/17/understand-react-lifecycle.html

   https://wiki.jikexueyuan.com/project/react/component-specs-lifecycle.html

   https://zhuanlan.zhihu.com/p/38030418

   https://zhuanlan.zhihu.com/p/26027085

posted @ 2019-09-01 14:58  iszhangjin  阅读(269)  评论(0编辑  收藏  举报