生命周期是框架为我们提供的用于了解程序当前运行阶段的一个钩子。
旧生命周期
挂载阶段(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(以内) 暂停一下更新,返回来继续渲染动画。
对于异步渲染,现在渲染有两个阶段:reconciliation 和 commit 。前者过程是可以打断的,后者不能暂停,会一直更新界面直到完成。
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的返回值。