React从0开始(三):生命周期

216 阅读3分钟

这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战

初步学习了React的组件以及简单的方法后,该了解一下React的生命周期了,本文主要对React 16的生命周期进行学习与讲解

前言

1. React生命周期的三个阶段

初始化阶段 -> 更新阶段 -> 卸载阶段

一、先从React 16之前的生命周期看起

下面是旧版的生命周期图: image.png

react生命周期(旧).png

主要生命周期解读:

  1. componentWillMount:页面挂载前的一个阶段
  2. componentDidMount:页面挂载完成后的一个生命周期,通常可以通过这一生命周期对页面的数据进行初始化(如网络请求等操作)
  3. componentWillRecieveProps:这一生命周期往往在最初render时不会被触发,顾名思义,通常是父组件传入的props发生改变后导致的重新渲染,这一生命周期被触发,但是若父子组件不断传递状态则有可能导致props不断刷新,导致页面死循环
  4. shouldComponentUpdate:通过判断状态是否发生了改变从而决定是否要触发重新渲染,可以用于做性能优化
  5. componentWillUpdate:更新阶段,shouldComponentUpdate返回true后触发
  6. componentDidUpdate:更新完成,可以访问到新元素
  7. componentWillUnmount:卸载阶段,可用于进行一些清理工作

二、React 16.3的生命周期

image.png

三、React 16.4的生命周期

下面是React 16.4的生命周期图: image.png

React 16.3React 16.4生命周期之间的区别:getDerivedStateFromPropsReact 16.4版本贯穿整个Update阶段,而在React 16.3版本中仅受到props的影响

React 16.4与旧版本生命周期的对比与改进:

  1. React 16.4弃用了以下几个不安全(UNSAFE)的生命周期:
    • componentWillMount:使用误区——在componentWillMount运行结束后会立即调用render,但是开发者异步请求的数据并未被正常渲染到,会导致初次渲染时空数据的问题
    • componentWillRecieveProps:父组件的props会触发这一生命周期,但其实只要父组件重新渲染,这一生命周期也会触发,其次使用该生命周期的子组件若调用父组件传来的函数导致父组件重新渲染,则会陷入渲染死循环
    • componentWillUpdate:组件初次渲染不会触发该阶段
  2. React 16.4新增了以下几个生命周期:
    • 静态方法 static getDerivedStateFromProps:静态方法不会被组件实例继承,因此该方法无法通过this来获取组件实例的方法或数据。该方法在组件每次渲染之前被调用,函数会返回一个对象用来更新state(函数传入新的props和当前state,根据新的props按照开发者逻辑对state进行调整,最后返回对象对state进行更新,返回null则不更新)
    • getSnapshotBeforeUpdate:该方法的任何返回值都作为第三个参数传给componentDidUpdate生命周期,相当于是在DOM更新前对元素进行一个当前状态的快照

四、注意事项

  • componentWillRecieveProps的触发不仅仅是因为父组件props有改变。只要父组件重新渲染,就会触发这一方法,且可能会因子组件改变父组件状态导致渲染死循环
  • 不要在componentWillMount方法内添加事件监听,因为挂载流程可以被React多次打断,也就可以多次触发componentWillMount,会导致内存泄漏
  • componentWillXXX在未来会因异步渲染的机制导致其在挂载阶段被打断多次,因此只希望触发一次的方法(如请求)应放在componentDidMount
  • React在新版会确保用户看到最新的UI之前刷新componentWillUpdatecomponentDidUpdate之间的setState操作,在这一过程中进行setState会导致渲染死循环