React生命周期分为15和16两个不同的版本
React15生命周期
React15有四个不同的阶段
- 初始化(initialization)
- 挂载阶段(Mounting)
- 更新阶段(Updating)
- 卸载阶段
初始化
constructor()
- 组件一创建就会调用 es6 class类中的 constructor 方法(最先执行)
- super(props)`用来调用类的构造方法( constructor() ), 也将父组件的props注入给子组件,子组件中props只读不可变,state可变
- constructor()用来做一些组件的初始化工作,如定义this.state的初始内容
挂载阶段
componentWillMount()
在组件挂载到DOM前调用,且只会被调用一次,在这边调用this.setState不会引起组件重新渲染,也可以把写在这边的内容提前到constructor()中,所以项目中很少用,它代表的过程是组件已经经历了constructor()初始化数据后,但是还未渲染DOM时。
render()
根据组件的props和state(两者的重传递和重赋值,无论值是否有变化,都可以引起组件重新render) ,当父组件的 render 函数被运行时, 它的子组件的 render 函数也会被重新运行
return 一个React元素(描述组件,即JSX模板),不负责组件实际渲染工作,之后由React自身根据此元素去渲染出页面DOM。render是纯函数(Pure function:函数的返回结果只依赖于它的参数;函数执行过程里面没有副作用),不能在里面执行this.setState,会有改变组件状态的副作用。
componentDidMount()
组件挂载到DOM后调用,且只会被调用一次
更新阶段
componentWillReceiveProps(nextProps)
- 只跟父组件传过来的 props 的变化有关,所以只有能接受 props 参数的子组件才有这个方法
- 此方法只调用于props引起的组件更新过程中,参数nextProps是父组件传给当前组件的新props
- 而且这个组件第一次存在于父组件的是时候不会被执行(就是第一次不会执行,以后如果 nextProps 参数有变化才会被执行
shouldComponentUpdate(nextProps, nextState)
- 主要用于性能优化(部分更新)
- 唯一用于控制组件重新渲染的生命周期,由于在react中,setState以后,state发生变化,组件会进入重新渲染的流程,在这里return false可以阻止组件的更新
- 因为react父组件的重新渲染会导致其所有子组件的重新渲染,这个时候其实我们是不需要所有子组件都跟着重新渲染的,因此需要在子组件的该生命周期中做判断
componentWillUpdate(nextProps, nextState)
在调用render方法前执行,在这边可执行一些组件更新发生前的工作,一般较少用
render
componentDidUpdate(prevProps, prevState)
此方法在组件更新后被调用,可以操作组件更新的DOM,prevProps和prevState这两个参数指的是组件更新前的props和state
卸载阶段
componentWillUnmount
此方法在组件被卸载前调用,可以在这里执行一些清理工作,比如清楚组件中使用的定时器,清楚componentDidMount中手动创建的DOM元素等,以避免引起内存泄漏。
React16生命周期
新引入了两个新的生命周期函数
- getDerivedStateFromProps(nextProps, prevState)
- getSnapshotBeforeUpdate(prevProps, prevState)
getDerivedStateFromProps(nextProps, prevState)
- 它应该返回一个对象来更新状态,或者返回null来不更新任何内容
- 代替componentWillReceiveProps()。老版本中的componentWillReceiveProps()方法判断前后两个 props 是否相同,如果不同再将新的 props 更新到相应的 state 上去。这样做一来会破坏 state 数据的单一数据源,导致组件状态变得不可预测,另一方面也会增加组件的重绘次数。在 componentWillReceiveProps 中,我们一般会做以下两件事,一是根据 props 来更新 state,二是触发一些回调,如动画或页面跳转等。在老版本的 React 中,这两件事我们都需要在 componentWillReceiveProps 中去做。而在新版本中,官方将更新 state 与触发回调重新分配到了 getDerivedStateFromProps 与 componentDidUpdate 中,使得组件整体的更新逻辑更为清晰。而且在 getDerivedStateFromProps 中还禁止了组件去访问 this.props,强制让开发者去比较 nextProps 与 prevState 中的值,以确保当开发者用到 getDerivedStateFromProps 这个生命周期函数时,就是在根据当前的 props 来更新组件的 state,而不是去做其他一些让组件自身状态变得更加不可预测的事情
getSnapshotBeforeUpdate(prevProps, prevState)
代替componentWillUpdate。常见的 componentWillUpdate 的用例是在组件更新前,读取当前某个 DOM 元素的状态,并在 componentDidUpdate 中进行相应的处理。
这两者的区别在于:
- 在 React 开启异步渲染模式后,在 render 阶段读取到的 DOM 元素状态并不总是和 commit 阶段相同,这就导致在componentDidUpdate 中使用 componentWillUpdate 中读取到的 DOM 元素状态是不安全的,因为这时的值很有可能已经失效了。
- getSnapshotBeforeUpdate 会在最终的 render 之前被调用,也就是说在 getSnapshotBeforeUpdate 中读取到的 DOM 元素状态是可以保证与 componentDidUpdate 中一致的。
此生命周期返回的任何值都将作为参数传递给componentDidUpdate()。
参考自