如果你对 React 生命周期一知半解,那么请看这篇文章!

一、笔者述 :

现在的时间是 2019年11月2日,React 生命周期较以前也有了很大变化。
但是为了更清楚直观的理解当前 React 的生命周期,笔者会从更新之前版本的 React 生命周期说起 :
并且笔者不是大佬,暂时还不会去从源码角度去揭示或者验证写什么,此篇文章仅仅是供自己以后查看和供小白们参考。

二、React 生命周期 ( 以前版本 )

1. 生命周期方法 :

  • getDefaultProps
  • getInitalState
  • constructor
  • componentWillMount
  • render
  • componentDidMount
  • componentWillReceiveProps
  • shouldComponentUpdate
  • componentWillUpdate
  • componentDidUpdate
  • componentWillUnMount

2. 工作流程 [正常情况下 - 5 个场景]:

  • 场景一 : 仅仅只是渲染了节点元素,并没有通过事件或者异步任务来更新 state 时,其经过生命周期的流程是这样的 :

getDefaultProps -> getInitalState -> constructor -> componentWillMount -> render -> componentDidMount

用 UML 建模来表示就是这样 :
在这里插入图片描述

  • 场景二 : 在场景一的基础上通过触发事件或者异步任务等,更新了 state 其经过生命周期的流程是这样的 :

handleEvent -> shouldComponentUpdate -> componentWillUpdate -> render -> componentDidUpdate

用 UML 建模来表示就是这样 :
在这里插入图片描述
这里有个比较有趣的生命周期方法,就是 shouldComponentUpdate ,因为该方法需要有返回值(布尔类型),也就是说返回 true 则继续向下执行 componentWillUpdate 然后 render ,如果返回 false 则不会向下继续执行 componentWillUpdate ,而是直接保持原来的状态,你会发现界面的 UI 也没有变化。
所以因为 shouldComponentUpdate 如此有趣,在这里我们或许可以通过属性判断来优化 React 组件在运行过程中的性能!

  • 场景三 : 通过事件或者异步任务等执行了 UnMountComponentAtNode(container) 而卸载 React 组件
    其经过生命周期的流程是这样的 :

handleEvent / componentDidMount / componentDidUpdate -> componentWillUnMount

须知 UnMountComponentNodeAt(container) 方法中的参数是一个真实的表示当前 React 根组件对应的 dom 节点。
至于为什么在 componentDidMountcomponentDidUpdate 中也可以执行这个操作,因为就拿 React 整个的生命周期来说只有 componentDidMount【组件已挂载】componentDidUpdate【组件已更新】 这两个周期函数在运行的时候当时的 React 组件都已经被映射成真实的 dom 元素了,所以才可能获取得到真实的 dom 节点,尽管直接操作 dom 是不被提倡的,但是在特定条件下我们也别无选择不是吗 ?
用 UML 建模来表示就是这样 :

在这里插入图片描述

  • 场景四 : 父组件引发了 props 值的变动
    其经过生命周期的流程是这样的 :

componentWillReceiveProps -> shouldComponentUpdate -> componentWillUpdate -> componentDidUpdate

用 UML 建模来表示就是这样 :
在这里插入图片描述
所以说白了 componentWillReceiveProps 仅仅是会在所被注入的 props 变动的时候才会执行,并且之后继续走 shouldComponentMount 的逻辑。

  • 场景五 : 调用 forceUpdate() 导致跳过 shouldComponentUpdate 直接继续执行 componentWillUpdaterendercomponentDidUpdate
    用 UML 建模来表示就是这样 :
    在这里插入图片描述
    为什么调用 forceUpdate 会跳过 shouldComponentUpdate 呢 ?
    -1). 简单的通过翻译便可知晓一部分原因 : force : 译为【暴力;力量】should : 译为【应该;应当】
    所以当我们打算执行 "确定" 了,我们还多次一举的去执行 "不确定" 做什么呢 ?
    -2). 如果页面上有些数据不是通过 state 挂载的,就是一些普通的变量,但是你也想通过触发事件去更改页面上的值,此时你在 handleClick 中无论怎么改值,可就是不会 render ,相应的页面上那个有纯变量渲染的值也是不会变的咯 ~ 。所以这种场景下就可以调用 forceUpdate 进行强制更新,届时你会发现页面上那个由纯变量渲染的值,也变成了你在 handleClick 中改的值。目的也就达到了。此时我们涉及的仅仅是普通变量,不涉及 state,所以也没有必要去走 shouldComponentUpdate

  • 所以以上 5 个场景基本上把整个 以前版本 的 React 生命周期囊括在内了。 所以下面贴出上述 5 个场景使用的代码以及 gif 参考动图。

-1). 场景一的配套代码以及动图 :
代码 :

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

// App 组件
class App extends Component {

    static propTypes() {
        console.log("propTypes ...");
    }

    static defaultProps() {
        console.log("defaultsProps ...");
    }

    // React 组件的构造器
    constructor(props) {
        super(props);
        console.log("constructor ...");
        // 初始化 state
        this.state = {
            name: "FruitJ"
        };

    }

    componentWillMount() {
        console.log("componentWillMount ...");
    }

    componentDidMount() {
        console.log("componentDidMount ...");
    }

    render() {

        console.log("render ...");
        return (
            <div>
                <span>{ this.state.name }</span>
            </div>
        );
    }

    componentWillReceiveProps(nextProps, nextContext) {
        console.log("componentWillReceiveProps ...");
    }

    shouldComponentUpdate(nextProps, nextState, nextContext) {
        console.log("shouldComponentUpdate ...");
        return true;
    }

    componentWillUpdate(nextProps, nextState, nextContext) {
        console.log("componentWillUpdate ...");
    }


    componentDidUpdate(prevProps, prevState, snapshot) {
        console.log("componentDidUpdate ...");
    }

    componentWillUnmount() {
        console.log("componentWillUnmount ...");
    }
}
export default App;

动图 :
在这里插入图片描述

-2). 场景二的配套代码以及动图 :
代码 :

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
// App 组件
class App extends Component {

    static propTypes() {
        console.log("propTypes ...");
    }

    static defaultProps() {
        console.log("defaultsProps ...");
    }

    // React 组件的构造器
    constructor(props) {
        super(props);
        console.log("constructor ...");
        // 初始化 state
        this.state = {
            name: "FruitJ"
        };

    }

    componentWillMount() {
        console.log("componentWillMount ...");
    }

    componentDidMount() {
        console.log("componentDidMount ...");
    }

    handleClick = () => {

        // 更新 state
        this.setState({
           name: "LJ"
        });
        console.log("handleClick ...");
    };

    render() {

        console.log("render ...");
        return (
            <div>

                <span>{ this.state.name }</span>
                <button onClick = { this.handleClick }>切换</button>
            </div>
        );
    }

    componentWillReceiveProps(nextProps, nextContext) {
        console.log("componentWillReceiveProps ...");
    }

    shouldComponentUpdate(nextProps, nextState, nextContext) {
        console.log("shouldComponentUpdate ...");
        return true;
    }

    componentWillUpdate(nextProps, nextState, nextContext) {
        console.log("componentWillUpdate ...");
    }


    componentDidUpdate(prevProps, prevState, snapshot) {
        console.log("componentDidUpdate ...");
    }

    componentWillUnmount() {
        console.log("componentWillUnmount ...");
    }
}
export default App;

动图 :
在这里插入图片描述
-3). 场景三的配套代码以及动图 :
代码 :

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

let temp = 9;

// App 组件
class App extends Component {

    static propTypes() {
        console.log("propTypes ...");
    }

    static defaultProps() {
        console.log("defaultsProps ...");
    }

    // React 组件的构造器
    constructor(props) {
        super(props);
        console.log("constructor ...");
        let a = "ssassss";
        // 初始化 state
        this.state = {
            name: "FruitJ"
        };

    }

    componentWillMount() {
        console.log("componentWillMount ...");
    }

    componentDidMount() {
        console.log("componentDidMount ...");
    }

    handleClick = () => {

        // 更新 state
        this.setState({
           name: "LJ"
        });
        console.log("handleClick ...");
    };

    handleRemoveClick = (ev) =>{
      ReactDOM.unmountComponentAtNode(ev.target.parentNode.parentNode);
    };

    render() {

        console.log("render ...");
        return (
            <div>

                <span>{ this.state.name }</span>
                <button onClick = { this.handleClick }>切换</button>
                <button onClick = {this.handleRemoveClick}>remove ReactDOM</button>
            </div>
        );
    }

    componentWillReceiveProps(nextProps, nextContext) {
        console.log("componentWillReceiveProps ...");
    }

    shouldComponentUpdate(nextProps, nextState, nextContext) {
        console.log("shouldComponentUpdate ...");
        return true;
    }

    componentWillUpdate(nextProps, nextState, nextContext) {
        console.log("componentWillUpdate ...");
    }
    componentDidUpdate(prevProps, prevState, snapshot) {
        console.log("componentDidUpdate ...");
    }

    componentWillUnmount() {
        console.log("componentWillUnmount ...");
    }
}
export default App;

动图 :
在这里插入图片描述
-4). 场景四的配套代码以及动图 :
代码 :
父组件 :

import React, { Component } from 'react';

import SubComponent from './SubComponent';

export default class Index extends Component {// 定义组件

    constructor(props) {
        super(props);
        this.state = {
          name: "FruitJ"
        };

        console.log("Parent Component's constructor ...");
    }

    componentWillMount() {
        console.log("Parent Component's componentWillMount ...");
    }


    componentDidMount() {
        console.log("Parent Component's componentDidMount ...");
    }


    handleChangeName = () => {
        this.setState({
            name: "LJ"
        })
    };

    render() {
        return (
            <div>
                <SubComponent name = { this.state.name }
                              handleChangeName = { this.handleChangeName }
                />
            </div>
        );
    }

    componentWillReceiveProps(nextProps) {
        console.log("Parent Component's componentWillReceiveProps ...");
    }

    // 此处的 nextState 指向的是此次 state
    shouldComponentUpdate(nextProps, nextState, nextContext) {
        console.log("Parent Component's shouldComponentUpdate ...");
        return true;
    }

    // 此处的 nextState 指向的是此次 state
    componentWillUpdate(nextProps, nextState) {
        console.log("Parent Component's componentWillUpdate ...");
    }


    // 此处的 prevState 指向的是此次 state 中的上一个 state
    componentDidUpdate(prevProps, prevState, snapshot) {
        console.log("Parent Component's componentDidUpdate ...");
    }

    componentWillUnmount() {
        console.log("Parent Component's componentWillUnmount ...");
    }
}

子组件 :

import React, { Component } from 'react';

export default class SubComponent extends Component {
    constructor(props) {
        super(props);
        console.log("Sub Component's constructor ...");
    }

    componentWillMount() {
        console.log("Sub Component's componentWillMount ...");
    }

    componentDidMount() {
        console.log("Sub Component's componentDidMount ...");
    }


    handleClick = () => {
        this.props.handleChangeName();
    };

    render() {



        return (
            <div>
                <span>{ this.props.name }</span>
                <button onClick = { this.handleClick }>切换</button>
            </div>
        );
    }

    // 此处的 nextProps 指向的是此次的 props
    componentWillReceiveProps(nextProps, nextContext) {
        console.log("Sub Component's componentWillReceiveProps ...");
    }

    // 此处的 nextProps 指向的是此次的 props
    shouldComponentUpdate(nextProps, nextState, nextContext) {
        console.log("Sub Component's shouldComponentUpdate ...");


        return true;
    }

    // 此处的 nextProps 指向的是此次的 props
    componentWillUpdate(nextProps, nextState) {
        console.log("Sub Component's componentWillUpdate ...");
    }

    // 此处的 prevProps 指向的是上一次的 props
    componentDidUpdate(prevProps, prevState, snapshot) {
        console.log("Sub Component's componentDidUpdate ...");
    }
}

动图 :
在这里插入图片描述
-5). 场景五的配套代码以及动图 :
代码 :
调用 forceUpdate() 之前 :

import React, { Component } from 'react';
import ReactDOM from 'react-dom';

let temp = 9;

// App 组件
class App extends Component {

    static propTypes() {
        console.log("propTypes ...");
    }

    static defaultProps() {
        console.log("defaultsProps ...");
    }

    // React 组件的构造器
    constructor(props) {
        super(props);
        console.log("constructor ...");
        // 初始化 state
        this.state = {
            name: "FruitJ"
        };

    }

    componentWillMount() {
        console.log("componentWillMount ...");
    }

    componentDidMount() {
        console.log("componentDidMount ...");
    }
    handleClick = () => {

        // 更新 state
        this.setState({
           name: "LJ"
        });
        console.log("handleClick ...");
    };

    handleRemoveClick = (ev) =>{
        ReactDOM.unmountComponentAtNode(ev.target.parentNode.parentNode);
    };

    handleChangeNum = () => {
        temp = 66;
        // this.forceUpdate();
    };

    render() {

        console.log("render ...");
        return (
            <div>

                <span>{ this.state.name }</span>
                <button onClick = { this.handleClick }>切换</button>
                <button onClick = {this.handleRemoveClick}>remove ReactDOM</button>
                <span>{ temp }</span>
                <button onClick = { this.handleChangeNum }>切换</button>
            </div>
        );
    }

    componentWillReceiveProps(nextProps, nextContext) {
        console.log("componentWillReceiveProps ...");
    }

    shouldComponentUpdate(nextProps, nextState, nextContext) {
        console.log("shouldComponentUpdate ...");
        /*console.log(nextProps);
        console.log(nextState);
        console.log(nextContext);
        console.log("-- end --");*/
        return true;
    }

    componentWillUpdate(nextProps, nextState, nextContext) {
        console.log("componentWillUpdate ...");
    }
    componentDidUpdate(prevProps, prevState, snapshot) {
        console.log("componentDidUpdate ...");
    }

    componentWillUnmount() {
        console.log("componentWillUnmount ...");
    }
}
export default App;

是无法更新由纯变量渲染的值的。
动图 :
在这里插入图片描述
但是如果调用 forceUpdate() ,页面上由纯变量渲染的值发生了变化。
针对上面贴出的代码,将 // forceUpdate(); -- 去掉注释 --> forceUpdate(); 即可。
动图 :
在这里插入图片描述

  • 最后附上两张笔者绘制的 React 生命周期 (以前版本) 的流程图,两张表述的意思一致只不过绘制思路不同。
    -1).
    在这里插入图片描述
    -2).
    在这里插入图片描述

三、React 生命周期 ( 当前版本 )

React 当前版本的生命周期的改动比较大。
是将 componentWillMountcomponentWillUpdatecomponentWillReceiveProps 三个生命周期方法去掉,取而代之的是 static getDerivedStateFromPropsgetSnapshotBeforeUpdate 方法。没错这里 getDerivedStateFormProps 是一个静态方法。

推出此 2 个生命周期方法而废黜原来那 3 个生命周期方法的原因 :

一年多来,React团队一直在努力实现异步渲染。上个月,Dan在JSConf Iceland上的演讲中,展示了一些令人兴奋的异步渲染解锁新可能性。现在,我们想与您分享在使用这些功能时所学到的一些经验教训,以及一些有助于启动异步渲染准备组件的方法。
我们学到的最大的经验教训之一是,我们的某些旧组件生命周期倾向于鼓励不安全的编码实践。他们是:

  • componentWillMount
  • componentWillReceiveProps
  • componentWillUpdate
    这些生命周期方法经常被误解和巧妙地滥用。此外,我们预计它们的潜在滥用可能会在异步渲染方面带来更多问题。因此,在即将发布的版本中,我们将为这些生命周期添加“ UNSAFE_”前缀。(在这里,“不安全”不是指安全性,而是表示使用这些生命周期的代码在React的未来版本中更有可能出现错误,尤其是在启用异步渲染后。)

---------- 引自 : 布莱恩·沃恩(Brian Vaughn)React 的官方 blog

笔者谈谈个人的理解【仅供参考】 :
相比于 Vue 的生命周期,笔者认为 React 的生命周期有些冗余与复杂,并且就像上面说的有的周期方法甚至还会存在一些隐患 :
一 一 道来 :

  • React 【以前版本】的 componentWillMount 这个周期函数的存在让笔者觉得没有意义,因为如果你是企图在组件 Mount 之前就拿到这个异步数据的话,在 componentWillMount 里面搞是完全没有意义的。
    即使是在组件 Mount 之前异步请求数据,其也会在 render 后被返回。
    譬如说 : 如果子组件中某个需要渲染的值是来源于父组件注入的,那么如果父组件注入的这个值在更新的时候是在 componentWillMount 中异步获取的话,恰好网络堵塞,就可能导致一种情况,子组件会长时间拿不到想要的值,如果子组件中要是再拿这个做一些操作,例如判断等 … 直接就会导致结果偏差。
    用代码和动图来说明一下 : 【子组件要拿父组件的值做判断,及时拿到弹出 yes ,反之弹出 no
    代码 :
    父组件 :
import React, { Component } from 'react';

import SubComponent from './SubComponent';

export default class Index extends Component {// 定义组件

    constructor(props) {
        super(props);
        this.state = {
          name: "FruitJ"
        };

        console.log("Parent Component's constructor ...");
    }

    componentWillMount() {
        console.log("Parent Component's componentWillMount ...");

        fetch("../resource/data.json")
            .then((res) => {
                return res.json();
            })
            .then((data) => {
                console.log("--------");
                console.log(data);
                setTimeout(() => {
                    this.setState({
                        name: data.animalName
                    })
                }, 3000);

            })
            .catch((err) => {
                console.error(err)
            });
    }


    componentDidMount() {
        console.log("Parent Component's componentDidMount ...");
    }


    handleChangeName = () => {
        this.setState({
            name: "LJ"
        })
    };

    render() {
        return (
            <div>
                <SubComponent name = { this.state.name }
                              handleChangeName = { this.handleChangeName }
                />
            </div>
        );
    }

    componentWillReceiveProps(nextProps) {
        console.log("Parent Component's componentWillReceiveProps ...");
    }

    // 此处的 nextState 指向的是此次 state
    shouldComponentUpdate(nextProps, nextState, nextContext) {
        console.log("Parent Component's shouldComponentUpdate ...");
        return true;
    }

    // 此处的 nextState 指向的是此次 state
    componentWillUpdate(nextProps, nextState) {
        console.log("Parent Component's componentWillUpdate ...");
    }


    // 此处的 prevState 指向的是此次 state 中的上一个 state
    componentDidUpdate(prevProps, prevState, snapshot) {
        console.log("Parent Component's componentDidUpdate ...");
    }

    componentWillUnmount() {
        console.log("Parent Component's componentWillUnmount ...");
    }
}

子组件 :

import React, { Component } from 'react';

export default class SubComponent extends Component {// 定义组件

    constructor(props) {
        super(props);
        console.log("Sub Component's constructor ...");
        this.state = {
            name: "Linux"
        };
    }

    componentWillMount() {
        console.log("Sub Component's componentWillMount ...");
    }

    componentDidMount() {

        this.props.name === "tiger" ? alert("yes"): alert("no");
        console.log("Sub Component's componentDidMount ...");
    }


    handleClick = () => {
        this.props.handleChangeName();
    };

    render() {



        return (
            <div>
                <span>{ this.props.name }</span>
                <button onClick = { this.handleClick }>切换</button>
                <span>{ this.state.name }</span>
            </div>
        );
    }

    // 此处的 nextProps 指向的是此次的 props
    componentWillReceiveProps(nextProps, nextContext) {
        console.log("Sub Component's componentWillReceiveProps ...");

    }

    // 此处的 nextProps 指向的是此次的 props
    shouldComponentUpdate(nextProps, nextState, nextContext) {
        console.log("Sub Component's shouldComponentUpdate ...");


        return true;
    }

    // 此处的 nextProps 指向的是此次的 props
    componentWillUpdate(nextProps, nextState) {
        console.log("Sub Component's componentWillUpdate ...");
    }

    // 此处的 prevProps 指向的是上一次的 props
    componentDidUpdate(prevProps, prevState, snapshot) {
        console.log("Sub Component's componentDidUpdate ...");
    }
}

data.json :

{
  "animalName": "tiger"
}

动图 :
在这里插入图片描述

    • React 【以前版本】的 componentWillUpdate 这个周期函数笔者认为稍有疏忽就可能出现一些问题,如果这里你不小心更新了 state 的话,对不起等待浏览器内存溢出吧【只不过 React 直接抛出了异常,结束了循环调用】,原因很简单根据 React 【以前版本】 的生命周期流程思考 : 这一轮的更新操作走到了 componentWillUpdate 的时候又 setState 了一下,走完一圈还是会回到此函数,重蹈覆辙,直至耗尽内存。React 在这强行抛出异常某些方面是为了防止出现这种情况。
      用代码和动图来说明一下 :
      代码 :
import React, { Component } from 'react';
import ReactDOM from 'react-dom';

let temp = 9;

// App 组件
class App extends Component {

    static propTypes() {
        console.log("propTypes ...");
    }

    static defaultProps() {
        console.log("defaultsProps ...");
    }

    // React 组件的构造器
    constructor(props) {
        super(props);
        console.log("constructor ...");
        // 初始化 state
        this.state = {
            name: "FruitJ",
            animalName: "temp"
        };

    }

    componentWillMount() {
        console.log("componentWillMount ...");
    }

    componentDidMount() {

        console.log("componentDidMount ...");
    }

    handleClick = () => {

        // 更新 state
        this.setState({
           name: "LJ"
        });
        console.log("handleClick ...");
    };

    handleRemoveClick = (ev) =>{
        ReactDOM.unmountComponentAtNode(ev.target.parentNode.parentNode);
    };

    handleChangeNum = () => {
        temp = 66;
        this.forceUpdate();
    };

    render() {

        console.log("render ...");
        return (
            <div>

                <span>{ this.state.name }</span>
                <button onClick = { this.handleClick }>切换</button>
                <button onClick = {this.handleRemoveClick}>remove ReactDOM</button>
                <span>{ temp }</span>
                <button onClick = { this.handleChangeNum }>切换</button>
                { this.state.animalName }
            </div>
        );
    }

    componentWillReceiveProps(nextProps, nextContext) {
        console.log("componentWillReceiveProps ...");
    }

    shouldComponentUpdate(nextProps, nextState, nextContext) {
        console.log("shouldComponentUpdate ...");
        return true;
    }

    componentWillUpdate(nextProps, nextState, nextContext) {
        console.log("componentWillUpdate ...");
    }


    componentDidUpdate(prevProps, prevState, snapshot) {
        console.log("componentDidUpdate ...");
    }

    componentWillUnmount() {
        console.log("componentWillUnmount ...");
    }
}
export default App;

在这里插入图片描述

    • React 【以前版本】的 componentWillReceiveProps 这个周期函数就与上面 布莱恩·沃恩(Brian Vaughn)在 React 的 blog 中说的那样,与一些其他的生命周期函数结合起来在 React 整个生命周期中会使程序变得更加复杂,组件难以维护。

1. 生命周期方法

  • getDefaultProps
  • getInitalState
  • static getDerivedStateFormProps
  • render
  • componentDidMount
  • shouldComponentUpdate
  • getSnapshotBeforeUpdate
  • componentDidMount
  • componentWillUnMount

2. 工作流程 [正常情况下 - 5 个场景]:

  • 场景一 : 仅仅只是渲染了节点元素,并没有通过事件或者异步任务来更新 state 时,其经过生命周期的流程是这样的 :

getDefaultProps -> getInitalState -> constructor -> getDerivedStateFromProps -> render -> componentDidMount

用 UML 建模来表示就是这样 :
在这里插入图片描述

  • 场景二 : 在场景一的基础上通过触发事件或者异步任务等,更新了 state 其经过生命周期的流程是这样的 :

handleEvent -> getDerivedStateFromProps -> shouldComponentUpdate -> getSnapshotBeforeUpdate -> componentDidUpdate

用 UML 建模来表示就是这样 :

在这里插入图片描述

  • 场景三 : 通过事件或者异步任务等执行了 UnMountComponentAtNode(container) 而卸载 React 组件
    其经过生命周期的流程是这样的 :

handleEvent -> componentWillUnMount

用 UML 建模来表示就是这样 :
在这里插入图片描述

  • 场景四 : 父组件引发了 props 值的变动
    其经过生命周期的流程是这样的 :

getDerivedStateFromProps -> shouldComponentUpdate -> render -> getSnapshotBeforeUpdate -> getSnapshotBeforeUpdate【父组件】-> componentDidUpdate

用 UML 建模来表示就是这样 :
在这里插入图片描述

  • 场景五 : 调用 forceUpdate() 导致跳过 shouldComponentUpdate 直接继续执行 rendergetSnapshotBeforeUpdatecomponentDidUpdate
    用 UML 建模来表示就是这样 :
    在这里插入图片描述
  • 所以以上 5 个场景基本上把整个 当前版本 的 React 生命周期囊括在内了。 所以下面贴出上述 5 个场景使用的代码以及 gif 参考动图。

-1). 场景一的配套代码以及动图 :
代码 :

import React, { Component } from 'react';

import ReactDOM from "react-dom";
export default class NewComponentLifeCycle extends Component {

    constructor(props) {
        super(props);
        console.log();
        this.state = {
            name: "FruitJ",
            age: 21
        };
    }

    // 此处的 state 指向的是此次 state
    static getDerivedStateFromProps(props, state) {
        console.log("getDerivedStateFromProps ...");
        return null;
    }
    componentDidMount() {
        console.log("componentDidMount ...");
    }
    render() {
        console.log("render ...");
        return (
            <div>
                <span>{ this.state.name }</span>
            </div>
        );
    }

    shouldComponentUpdate(nextProps, nextState, nextContext) {
        console.log("shouldComponentUpdate ...");
        return true;
    }

    getSnapshotBeforeUpdate(prevProps, prevState) {
        console.log("getSnapshotBeforeUpdate ...");
        return "Hello World!";
    }

    componentDidUpdate(prevProps, prevState, snapshot) {
        console.log("componentDidUpdate ...");
        console.log(snapshot);
    }

    componentWillUnmount() {
        console.log("componentWillUnmount ...");
    }
}

动图 :
在这里插入图片描述
-2). 场景二的配套代码以及动图 :
代码 :

import React, { Component } from 'react';
import ReactDOM from "react-dom";

export default class NewComponentLifeCycle extends Component {

    constructor(props) {
        super(props);
        console.log();
        this.state = {
            name: "FruitJ",
            age: 21
        };
    }

    // 此处的 state 指向的是此次 state
    static getDerivedStateFromProps(props, state) {
        console.log("getDerivedStateFromProps ...");
        return null;
    }


    componentDidMount() {
        console.log("componentDidMount ...");
    }


    handleClick = () => {
        console.log("handleClick ...");
        this.setState({
            name: "LJ"
        });
    };

    render() {
        console.log("render ...");
        return (
            <div>
                <span>{ this.state.name }</span>
                <button onClick = { this.handleClick }>切换</button>
            </div>
        );
    }

    shouldComponentUpdate(nextProps, nextState, nextContext) {
        console.log("shouldComponentUpdate ...");
        return true;
    }

    getSnapshotBeforeUpdate(prevProps, prevState) {
        console.log("getSnapshotBeforeUpdate ...");
        return "Hello World!";
    }

    componentDidUpdate(prevProps, prevState, snapshot) {
        console.log("componentDidUpdate ...");
        console.log(snapshot);
    }

    componentWillUnmount() {
        console.log("componentWillUnmount ...");
    }
}

动图 :
在这里插入图片描述
-3). 场景三的配套代码以及动图 :
代码 :

import React, { Component } from 'react';

import ReactDOM from "react-dom";

export default class NewComponentLifeCycle extends Component {

    constructor(props) {
        super(props);
        console.log();
        this.state = {
            name: "FruitJ",
            age: 21
        };
    }

    // 此处的 state 指向的是此次 state
    static getDerivedStateFromProps(props, state) {
        console.log("getDerivedStateFromProps ...");
        return null;
    }


    componentDidMount() {
        console.log("componentDidMount ...");
    }

    handleRemoveClick = (ev) => {
        ReactDOM.unmountComponentAtNode(ev.target.parentNode.parentNode);
    };

    render() {
        console.log("render ...");
        return (
            <div>
                <button onClick = { this.handleRemoveClick }>remove</button>
            </div>
        );
    }

    shouldComponentUpdate(nextProps, nextState, nextContext) {
        console.log("shouldComponentUpdate ...");
        return true;
    }

    getSnapshotBeforeUpdate(prevProps, prevState) {
        console.log("getSnapshotBeforeUpdate ...");
        return "Hello World!";
    }

    componentDidUpdate(prevProps, prevState, snapshot) {
        console.log("componentDidUpdate ...");
        console.log(snapshot);
    }

    componentWillUnmount() {
        console.log("componentWillUnmount ...");
    }
}

动图 :
在这里插入图片描述
-4). 场景四的配套代码以及动图 :
代码 :

import React, { Component } from 'react';

import NewComponentLCSub from './NewComponentLCSub';
import ReactDOM from "react-dom";
export default class NewComponentLifeCycle extends Component {

    constructor(props) {
        super(props);
        console.log();
        this.state = {
            name: "FruitJ",
            age: 21
        };
    }

    // 此处的 state 指向的是此次 state
    static getDerivedStateFromProps(props, state) {
        console.log("getDerivedStateFromProps ...");
        return null;
    }


    componentDidMount() {
        console.log("componentDidMount ...");
    }

    handleChangeAge = ()=> {
        this.setState({
            age: 22
        });
    };
   
    render() {
        console.log("render ...");
        return (
            <div>
                <NewComponentLCSub age = { this.state.age }
                                   handleChangeAge = { this.handleChangeAge }

                />
            </div>
        );
    }

    shouldComponentUpdate(nextProps, nextState, nextContext) {
        console.log("shouldComponentUpdate ...");
        return true;
    }

    getSnapshotBeforeUpdate(prevProps, prevState) {
        console.log("getSnapshotBeforeUpdate ...");
        return "Hello World!";
    }

    componentDidUpdate(prevProps, prevState, snapshot) {
        console.log("componentDidUpdate ...");
        console.log(snapshot);
    }

    componentWillUnmount() {
        console.log("componentWillUnmount ...");
    }
}

在这里插入图片描述
-5). 场景五的配套代码以及动图 :
代码 :

import React, { Component } from 'react';

import ReactDOM from "react-dom";

let temp = 9;

export default class NewComponentLifeCycle extends Component {

    constructor(props) {
        super(props);
        console.log();
        this.state = {
            name: "FruitJ",
            age: 21
        };
    }

    // 此处的 state 指向的是此次 state
    static getDerivedStateFromProps(props, state) {
        console.log("getDerivedStateFromProps ...");
        return null;
    }


    componentDidMount() {
        console.log("componentDidMount ...");
    }

    handleUpdateClick = () => {
        temp = 66;
        this.forceUpdate();
    };

    render() {
        console.log("render ...");
        return (
            <div>
                <span>{ temp }</span>
                <button onClick = { this.handleUpdateClick }>forceUpdate</button>
            </div>
        );
    }

    shouldComponentUpdate(nextProps, nextState, nextContext) {
        console.log("shouldComponentUpdate ...");
        return true;
    }

    getSnapshotBeforeUpdate(prevProps, prevState) {
        console.log("getSnapshotBeforeUpdate ...");
        return "Hello World!";
    }

    componentDidUpdate(prevProps, prevState, snapshot) {
        console.log("componentDidUpdate ...");
        console.log(snapshot);
    }

    componentWillUnmount() {
        console.log("componentWillUnmount ...");
    }
}

在这里插入图片描述

  • 最后附上一张笔者绘制的 React 生命周期 (当前版本) 的流程图。
    在这里插入图片描述

四、迁移

React 更换生命周期,应该会有一批项目逐步的向新版本上来迁移,如果工程量比较大的,也不用着急 ! 因为 React 官方在新发布的 React 版本中以前版本的生命周期函数还是可以使用的 !
没错,即使不加 UNSAFE_ 前缀也是可以使用的,但是 React 官方还是会建议在使用以前的周期函数最好加上 UNSAFE_ 前缀标识一下,这样不仅仅是与潮流同进,也是为了以后自己迁移自己项目的时候可以很清楚分辨出哪些是需要重构的。
当前的 React 版本虽然支持 以前版本 与 当前版本的 React 周期函数,但是不建议混用,只是为了让咱们提前熟悉并且让咱们有个逐步过渡的时间。
在这里插入图片描述

六、总述

React 是笔者刚刚接触的框架,本篇文章真的只是浅显的入个门,还有很多内容没有说,比如父子组件之间的生命周期的流程,但这些笔者认为就不需要摆出来说一会了,因为毫无疑问,父组件必须等待响应着子组件,仅此而已 ! 而且废黜了这三个生命周期函数在一定程度上使 React 组件使用起来更加的清爽并且减少了一些因为异步或是循环调用等引起的一些比较极端而又可笑的事情发生。

七、忠告

  • React 定义组件的时候除了路由组件等其他有特殊需求的以外,最好都定义为无状态组件【也就是纯函数】,这样性能会好一些。React 所提倡的就是多用无状态组件,甚至于说 Hooks 就可以将有状态组件变为无状态组件。
  • React 组件的嵌套层级越少越好。嵌套过多就可能 render 不到数据。
  • React 使用 React 周期函数前要了解每个周期函数的特点和作用,在合理的周期函数中做合理的事情。
  • 定期关注 React conf

笔者浅显的用代码跑了一遍流程将其分析一顿并记录在案,能力有限难免有所疏漏,如有谬误还请指出 !

参考链接 :

-1). React数据获取为什么一定要在componentDidMount里面调用?

-2). 组件的生命周期(运行阶段和销毁阶段)以及事件处理函数

-3). React.unmountComponentAtNode is not a function

-4). componentWillReceiveProps详解(this.props)状态改变检测机制

-5). 详解React生命周期(包括react16版)

-6). React生命周期详解

-7). React 生命周期

-8). react生命周期

-9). 添加链接描述

-10). react基本原理及性能优化

-11). React 避免重渲染

-12). forceUpdate setState有什么区别

-13). React总结(四)-- refs和forceUpdate

-14). Vue与React两个框架的区别和优势对比

-15). Update on Async Rendering

-16). React组件生命周期过程说明:forceUpdate强制更新

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值