React 新版本,老版本生命周期

React 生命周期

一.简介

在React中,每个组件提供了生命周期钩子函数去响应组件在不同时刻应该做的和可以做的事情.组件的挂载>数据更新阶段>卸载阶段

二.React 16版本的生命周期

由于React 16版本中对生命周期有所更改,所以这里介绍新老版本,现在一般不建议使用React15版本的,会报安全性警告

1.组件的挂载

React将组件渲染 > 构造DOM > 展示到页面的过程称为组件的挂载.

1.constructor()

constructor()是ES6中类的默认方法,通过new命令生成对象实例时自动调用该方法.其中的super()是class方法中的继承,它是使用extends关键字来实现的.子类必须在constructor()中调用super()方法,否则新建实例会报错.如果没有用到constructor(),React会默认添加一个空的constructor()`

constructor()用来做一些组件初始化的工作,比如定义this.state的初始内容,继承父类获取props

class BaseWorld extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            name: 'liuqiao'
        };
    }
    render() {
        console.log(this.props);
        return (
            <div>
                {this.state.name}
            </div>
        );
    }
}
2.static getDerivedStateFromProps(props,state)

组件在装载的时候,也就是组件在构建之后(虚拟DOM之后,实际DOM挂载之前),每次获取新的props或state之后,当props更改时触发,然后返回的对象将会与当前的状态合并,作为新的state,返回null则说明不需要更新state.

static getDerivedStateFromProps() {
    console.log('getDerivedStateFromProps');
    return null;
}

第一次的初始化组件以及后续的更新过程中(包括自身状态更新以及父传子)都会触发此生命周期. 一般不怎么使用这个钩子函数

3.render()

非常重要的钩子函数.React最重要的步骤,创建虚拟dom,进行diff算法,更新dom树都会在此进行.

render() {
    console.log('render');
    return (
        <div>
        </div>
    );
}
4.componentDidMount()

组件渲染之后,只调用一次,非常重要:表示dom准备就绪,动态数据请求已经初始化完成

componentDidMount() {
    console.log('----componentDidMount');
    // 开启长连接
    // 开定时器
    // 调接口
}

2.组件的数据更新阶段

1.static getDerivedStateFromProps(props,state)

只要props或state有更新,就会触发这个钩子函数,不常用

2.shouldComponentUpdate(nextProps, nextState)

用于判断组件是否需要更新.也就是相当于diff运算的开关,一般我们会在此钩子函数中进行相关的性能优化,比如我们设置在此对比前后两个props和states是否相同,如果相同则返回false阻止更新.因为相同的属性状态一定会生成相同的dom树,这样就不需要创造新的dom树和旧的dom树进行diff算法对比,节省大量性能,尤其是在dom结构复杂的时候

组件接受新的state或者props时调用.默认情况下,该方法返回true,当返回值为false时,则不再向下执行其他生命周期方法.

3.componentWillUpdata(nextProps, nextState)

组件加载时不调用,只有在组件将要更新时才调用,此时可以修改state

最后一次更改props和state的机会,组件将要更新的时候触发

4. render()

重新再渲染一遍组件,更新dom树

5.getSnapshotBeforeUpdate()

在最近的更改被提交到DOM元素前,render()之后,使得组件可以在更改之前获得当前值,此生命周期返回的任意值都会传给componentDidUpdate()的第三个参数。’,不常用’

6.componentDidUpdate()

dom更新完成时,更新DOM节点的操作可放在这里进行。

7.数据更新可以分为2中情况:
1.组件自身state更新

shouldComponentUpdate()>render()>getSnapshotBeforeUpdate()>componentDidUpdate()

2.传递过来的props更新

static getDerivedStateFromProps()>shouldComponentUpdate()>render()>getSnapshotBeforeUpdate()>componentDidUpdate()

3.组件的卸载

1.componentWillUnmount()

在组件卸载之前调用,可以在此方法中执行任何需要清理的工作,比如定时器,事件回收,取消网络请求等等,或者清理在componentDidMount()中创建的任何监听事件等

componentDidMount() {
    console.log('componentDidMount');
    // 开启长连接
    // 开定时器
    // 调接口
    this.timer=setTimeout(()=>{
        console.log('开启定时器');
        
    },1000);
}

//组件卸载阶段
componentWillUnmount(){
    this.timer&&clearTimeout(this.timer);
}

4.异常处理

1.componentDidCatch()

在渲染期间,生命周期方法或构造函数constructor()中发生错误时,将会调用componentDidCatch()方法

componentDidCatch(error,info){
    
}

不会处理捕获到下面引发的错误

  • componentDidCatch()本身错误
  • 服务端渲染(SSR)
  • 事件处理,因为事件处理不发生在React渲染时,报错不影响渲染
  • 异步代码

三.老版本生命周期

很多团队还没有更新到16版本,所以16版本之前的生命周期还是需要知道的.不过16版本也是基于之前的修改的,只不过是添加了几个钩子函数和弃用了几个钩子函数

图片描述

1.加载阶段

1.constructor()

加载的时候调用一次,可以初始化state,也可以接收props

2.getDefaultProps()

设置默认的props,也可以用defaultProps设置组件的默认属性

3.getInitialState()

初始化state,可以直接在constructor()中定义this.state

4.componentWillMount()

组件加载时只调用,以后组件更新不调用,整个生命周期只调用一次,此时可以修改state

5.render()

创建虚拟dom,进行diff运算,更新dom树都在此进行

6.componentDidMount()

组件渲染之后值调用一次

2.更新阶段

1.componentWillReceiveProps()

组件加载时不调用,组件接受新的props时调用

2.shouldComponentUpdate(nextProps,nextState)

组件接受到新的props或者state时调用,return true会更新dom,使用diff算法更新,return false阻止更新(不调用render) 性能优化的关键一环

3.componentWillUpdate(nextProps,nextState)

组件加载时不调用,只有组件在更新时才调用,此时可以修改state

4.render()

创建虚拟dom,diff运算,更新dom树

5.componentDidUpdate()

组件更新完成后调用

3.卸载阶段

1.componentWillUnmount()

在组件卸载之前调用,清理定时器,事件回收,释放某些东西时使用

import React from 'react';

export default class OldLife extends React.Component {
    constructor(props) {
        super(props);
        //getDefaultProps: 接收初始props
        //getInitialState: 初始化state
    }

    state = {

    }

    componentWillMount() {
        //组件挂载前触发
    }

    render() {
        return (
            <div>

            </div>
        );
    }

    componentDidMount() {
        //组件挂载完成后触发
    }

    componentWillReceiveProps(nextProps) {
        //接收到新的props时触发
    }

    shouldComponentUpdate(nextProps, nextState) {
        //进行性能优化   
        return true;
    }

    componentDidUpdate() {
        //组件更新后触发
    }

    componentWillUnmount() {
        //卸载时触发
        //this.timer&&clearTimeout(this.time
    }
}

四.总结(新老版本区别)

  • React16新的生命周期弃用了componentWillMount,componentWillReceiveProps,componentWillUpdate
  • 新增了 getDerivedStateFromProps,getSnapshotBeforeUpdate来代替弃用的三个钩子函数componentWillMount,componentWillReceiveProps,componentWillUpdate
  • React16并没有删除这三个钩子函数,但是不能和新的钩子函getDerivedStateFromProps,getSnapshotBeforeUpdate数混用,React17将会删除componentWillMount,componentWillReceiveProps,omponentWillUpdate
  • 新增了对错误的处理 componentDidCatch

老版本生命周期图示:

在这里插入图片描述
新版本生命周期图示:

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/liuqiao0327/article/details/107297106