组件从创建到销毁的一个过程,在这过程中,我们在每个特定阶段会触发一些方法。我们将这些方法称之为组件生命周期。组件生命周期主要可分为 初始化阶段、挂载阶段、更新阶段、卸载阶段。
自React V16.4发布以来,组件生命周期也产生了一些调整。本文会同时讲述两种生命周期的完整过程。

生命周期(旧)

如图所示,初始化阶段挂载阶段更新阶段卸载阶段
image.png
react生命周期(旧).png

  1. //初始化生命周期
  2. constructor(props) { //构造函数
  3. super(props);
  4. this.state = {date: new Date()};
  5. }
  6. static propTypes = { //对类本身增加属性
  7. name:PropTypes.string.isRequired,
  8. },
  9. this.state = {date: new Date()}; //对类的实例对象增加属性
  10. //挂载阶段生命周期
  11. componentWillMount(){
  12. //组件将要被挂载
  13. }
  14. render(){return JSX} //返回虚拟DOM
  15. componentDidMount(){
  16. //组件挂在完毕调用 一般用来开启定时器 开启监听 发送网络请求
  17. }
  18. //更新阶段生命周期
  19. componentWillReceiveProps(nextProps){
  20. //只要接到了新的props,componentWillReceiveProps就会被调用,即便新props与旧的完全一样
  21. //父组件调用render 子组件的componentWillReceiveProps就会触发 不论props值是否变更
  22. //1.上级组件render或者props变化
  23. //2.组件第一次挂载 不执行componentWillReceiveProps
  24. //3.触发时 可以通过this.props访问preProps
  25. }
  26. --> this.setState({}); //setState函数执行之后调用shouldComponentUpdate
  27. shouldComponentUpdate(nextProps,nextState){
  28. return boolean; //返回布尔值来控制组件是否更新 是更新 否不更新
  29. }
  30. --> this.forceUpdate({}); //forceUpdate函数执行之后调用componentWillUpdate
  31. componentWillUpdate(nextProps,nextState){
  32. //组件是否将要更新
  33. }
  34. render(){return JSX}
  35. componentDidUpdate(preProps,preState){
  36. //组件更新完毕 通常记录当前props state与preProps preState的差异 来实现业务需求
  37. }
  38. //卸载阶段生命周期
  39. componentWillUnmount(){
  40. //组件将要卸载 一般用于清除定时器
  41. }

生命周期(新)

如图所示为React V16.4生命周期,初始化阶段挂载阶段更新阶段卸载阶段
截屏2022-04-04 下午7.54.36.png

  1. //React V16.3将一些生命周期标记为UNSAFE_ 计划在未来的版本逐步移出这些生命周期
  2. //UNSAFE_componentWillReceiveProps(nextProps)
  3. //UNSAFE_componentWillMount()
  4. //UNSAFE_componentWillUpdate(nextProps, nextState)
  5. //初始化生命周期
  6. constructor(props) { //构造函数
  7. super(props);
  8. this.state = {date: new Date()};
  9. }
  10. static propTypes = { //对类本身增加属性
  11. name:PropTypes.string.isRequired,
  12. },
  13. //从props || state获取派生对象 不常用
  14. //由于16.4版本的修改 每次re-rendering都会调用该生命周期
  15. //1.父组件render 2.props change 3.this.setState() 4.this.forceUpdate()
  16. //getDerivedStateFromProps 用来取代 componentWillReceiveProps
  17. #1.react推出getDerivedStateFromProps生命周期的目的是为了代替componentWillReceiveProps
  18. #2.去实现基于props派生or更新state的诉求
  19. #特点
  20. #1.该方法是静态的,不能在函数内部使用this
  21. #2.该方法可以接收两个参数 来自父组件传递的props 组件自身的state
  22. #3.该方法需要返回一个对象(或者null)
  23. 3.1react需要根据这个返回值去更新(派生) 组件的state
  24. 3.2返回的对象会与该组件的state进行合并更新 不变更的时候return null
  25. static getDerivedStateFromProps(props, state){
  26. if(props || state ){ 根据props||state 返回派生对象
  27. return {...state,xxx}
  28. }
  29. return null
  30. }
  31. this.state = {date: new Date()}; //对类的实例对象增加属性
  32. //挂载阶段生命周期
  33. render(){return JSX}
  34. componentDidMount(){
  35. //组件挂在完毕调用 一般用来开启定时器 开启监听 发送网络请求
  36. }
  37. //更新阶段生命周期
  38. --> this.setState({}); //setState函数执行之后调用shouldComponentUpdate
  39. shouldComponentUpdate(nextProps,nextState){
  40. return boolean; //返回布尔值来控制组件是否更新 是更新 否不更新
  41. }
  42. --> this.forceUpdate({}); //forceUpdate函数执行之后调用render
  43. render(){return JSX} //返回的是虚拟DOM
  44. getSnapshotBeforeUpdate(prevProps, prevState){
  45. //在页面实际变化之前记录prevProps prevState并按业务需要返回快照对象(snapshot)
  46. //componentDidUpdate会接受到快照对象(snapshot)
  47. if(prevProps || prevState){
  48. return {...snapshot}
  49. }
  50. }
  51. componentDidUpdate(preProps,preState,snapshot){
  52. //组件更新完毕 通常记录当前props state与preProps preState的差异 来实现业务需求
  53. }
  54. //卸载阶段生命周期
  55. componentWillUnmount(){
  56. //组件将要卸载 一般用于清除定时器
  57. }

总结

新旧生命周期对比如下

  • 新生命周期在计划移除componentWillReceiveProps、componentWillUpdate、componentWillMount
  • 上面3个计划移除的生命周期,仍然可以使用但是会被标记UNSAFE_
  • 新增了static getDerivedStateFromProps、getSnapshotBeforeUpdate

    参考

  1. http://www.ayqy.net/blog/%E4%BB%8Ecomponentwillreceiveprops%E8%AF%B4%E8%B5%B7/
  2. https://segmentfault.com/a/1190000021827650 react生命周期详解
  3. https://www.jianshu.com/p/50fe3fb9f7c3 getDerivedStateFromProps详情解释
  4. https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/ react生命周期流程图
  5. https://www.icodebang.com/article/268804