请你说下React的生命周期(16.0和16.4)?

594 阅读5分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

前言

请你说下React的生命周期? 我想大多数面试React的时候都会问这个问题吧,虽然React Hook已形成主流,但这并不影响面试,可以说这是一到必考题。(反正我记得我面试的时候都问了(● ̄(エ) ̄●))

这个问题怎么说呢?算是基础中的基础,但其实有是一到很有趣的题,如果这道题答好了,应该能给面试官留个不错的印象👏🏻👏🏻

我先简单介绍下我了解的生命周期,之后在再说说我是怎么回答的,当然我的回答不一定是最好的,大家一起讨论讨论,欢迎在评论区讨论~

React v16.0前

这个版本应该是大家最熟悉的版本,现附上一张图:

1642556185644.jpg

总共分为四大阶段:Intialization(初始化)、Mounting(挂载)、Update(更新)、Unmounting(卸载)

Intialization(初始化)

在初始化阶段,我们会用到 constructor() 这个构造函数,如:

constructor(props) {
  super(props);
}
  • super的作用 用来调用基类的构造方法( constructor() ), 也将父组件的props注入给子组件,供子组件读取 (组件中props只读不可变,state可变)
  • 初始化操作,定义this.state的初始内容
  • 只会执行一次

Mounting(挂载)

componentWillMount:在组件挂载到DOM前调用

  • 这里面的调用的this.setState不会引起组件的重新渲染,也可以把写在这边的内容提到constructor(),所以在项目中很少。
  • 只会调用一次

render: 渲染

  • 只要props和state发生改变(无两者的重传递和重赋值,论值是否有变化,都可以引起组件重新render),都会重新渲染render。
  • return:是必须的,是一个React元素(UI,描述组件),不负责组件实际渲染工作,由React自身根据此元素去渲染出DOM。
  • render是纯函数(Pure function:返回的结果只依赖与参数,执行过程中没有副作用),不能执行this.setState。

componentDidMount:组件挂载到DOM后调用

  • 调用一次

Update(更新)

componentWillReceiveProps(nextProps):调用于props引起的组件更新过程中

  • nextProps:父组件传给当前组件新的props
  • 可以用nextProps和this.props来查明重传props是否发生改变(原因:不能保证父组件重传的props有变化)
  • 只要props发生变化就会,引起调用

shouldComponentUpdate(nextProps, nextState):性能优化组件

  • nextProps:当前组件的this.props
  • nextState:当前组件的this.state
  • 通过比较nextProps和nextState,来判断当前组件是否有必要继续执行更新过程。
  • 返回false:表示停止更新,用于减少组件的不必要渲染,优化性能
  • 返回true:继续执行更新
  • 像componentWillReceiveProps()中执行了this.setState,更新了state,但在render前(如shouldComponentUpdate,componentWillUpdate),this.state依然指向更新前的state,不然nextState及当前组件的this.state的对比就一直是true了

componentWillUpdate(nextProps, nextState):组件更新前调用

  • 在render方法前执行
  • 由于组件更新就会调用,所以一般很少使用
  • render:重新渲染

componentDidUpdate(prevProps, prevState):组件更新后被调用

  • prevProps:组件更新前的props
  • prevState:组件更新前的state
  • 可以操作组件更新的DOM

Unmounting(卸载)

componentWillUnmount:组件被卸载前调用

  • 可以在这里执行一些清理工作,比如清楚组件中使用的定时器,清楚componentDidMount中手动创建的DOM元素等,以避免引起内存泄漏

React v16.4

12b.png

大家可以看出与 v16.0的生命周期相比

新增了 getDerivedStateFromPropsgetSnapshotBeforeUpdate

取消了 componentWillMountcomponentWillReceivePropscomponentWillUpdate

getDerivedStateFromProps

getDerivedStateFromProps(prevProps, prevState):组件创建和更新时调用的方法

  • prevProps:组件更新前的props
  • prevState:组件更新前的state
  • 在React v16.3中,在创建和更新时,只能是由父组件引发才会调用这个函数,在React v16.4改为无论是Mounting还是Updating,也无论是什么引起的Updating,全部都会调用。
  • 类似于componentWillReceiveProps,不同的是getDerivedStateFromProps是一个静态函数,也就是这个函数不能通过this访问到class的属性,当然也不推荐使用
  • 如果props传入的内容不需要影响到你的state,那么就需要返回一个null,这个返回值是必须的,所以尽量将其写到函数的末尾。
  • 在组件创建时和更新时的render方法之前调用,它应该返回一个对象来更新状态,或者返回null来不更新任何内容。

getSnapshotBeforeUpdate

getSnapshotBeforeUpdate(prevProps,prevState):Updating时的函数,在render之后调用

  • prevProps:组件更新前的props
  • prevState:组件更新前的state
  • 可以读取,但无法使用DOM的时候,在组件可以在可能更改之前从DOM捕获一些信息(例如滚动位置)
  • 返回的任何指都将作为参数传递给componentDidUpdate()

讨论

回归问题,请你说下React的生命周期 ?

本菜鸟通常这样回答:

首先React生命周期有两个比较大的版本,一个是 16.0之前 和16.4之后的,16.0分为4个阶段,(执行顺序说一遍,此处省略300字),16.4 版本相比于16.0版本 新增了getDerivedStateFromPropsgetSnapshotBeforeUpdate,取消了除compentWillUnmount所有带Will的钩子函数,然后再把新增的两个钩子讲一通(此处省略500字),到最后时再说下 在 17.0的版本,官方彻底废除 componentWillMountcomponentWillReceivePropscomponentWillUpdate

不知道有没有让面试官眼前一亮呢?欢迎来评论区讨论

u=217188,3600500648&fm=253&fmt=auto&app=138&f=JPEG.webp