本文已参与「新人创作礼」活动,一起开启掘金创作之路。
前言
请你说下React的生命周期? 我想大多数面试React的时候都会问这个问题吧,虽然React Hook
已形成主流,但这并不影响面试,可以说这是一到必考题。(反正我记得我面试的时候都问了(● ̄(エ) ̄●))
这个问题怎么说呢?算是基础中的基础,但其实有是一到很有趣的题,如果这道题答好了,应该能给面试官留个不错的印象👏🏻👏🏻
我先简单介绍下我了解的生命周期,之后在再说说我是怎么回答的,当然我的回答不一定是最好的,大家一起讨论讨论,欢迎在评论区讨论~
React v16.0前
这个版本应该是大家最熟悉的版本,现附上一张图:
总共分为四大阶段: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
大家可以看出与 v16.0的生命周期相比
新增了 getDerivedStateFromProps 和getSnapshotBeforeUpdate
取消了 componentWillMount、componentWillReceiveProps、componentWillUpdate
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版本 新增了getDerivedStateFromProps
和 getSnapshotBeforeUpdate
,取消了除compentWillUnmount
所有带Will的钩子函数,然后再把新增的两个钩子讲一通(此处省略500字),到最后时再说下 在 17.0的版本,官方彻底废除 componentWillMount
、componentWillReceiveProps
、componentWillUpdate
不知道有没有让面试官眼前一亮呢?欢迎来评论区讨论