• React组件的生命周期


    React组件的生命周期

    组件的生命周期就是Reac的工作过程,就好比人有生老病死,自然界有日月更替,每个组件在网页中也会有被创建、更新和删除,如同有生命的机体一样。

    React组件的生命周期可以分为三个过程

    • 装载(挂载)过程(mount)就是组件第一次在DOM树中渲染的过程
    • 更新过程(update):组件被重新渲染的过程
    • 卸载过程(unmount)组件从DOM中被移除的过程

     

    一、装载过程

        依次调用如下函数constructorgetInitialStategetDefaultPropscomponentWillMountrendercomponentDidMount

        1、constructor

        就是ES6里的构造函数,创建一个组件类的实例,在这一过程中要进行两步操作:初始化state,绑定成员函数的this环境

    2、getInitialState和getDefaultProps

    这个两个函数可以不去深究,只会在用到React.createClass方法创造的组件类才会发生作用,所以ES6的方法定义的React组件中根本不会用到

    3、render

     render是React组件中最为重要的一个函数。这是react中唯一不可忽略的函数,在render函数中,只能有一个父元素。

    其中需要深入分析的是:render函数是一个纯函数,它并不进行实际上的渲染动作只是一个JSX描述的结构,最终是由React来进行渲染过程,render函数中不应该有任何操作,对页面的描述完全取决于this.state和this.props的返回结果,不能在render调用this.setState

         有一个公式总结的非常形象     UI=render(data)

    4、componentWillMount和componentDidMount

    这两个函数分别在render前后执行,componentWillMonut显得有些鸡肋,还没有任何东西展示,操作完全可以提前到constructor中来进行

    但是componentDidMount函数作用就大得多,由于这一过程通常只能在浏览器端调用,所以我们在这里获取异步数据,而且在componentDidMount调用的时候,组件已经被装载到DOM树上了,还有,可以在这里执行其他库的代码,比如Jquery

    二、更新过程

    简单来说就是propsstate被修改的过程,依次调用componentWillReceivePropsshouldComponentUpdatecomponentWillUpdaterendercomponentDidUpdate

    1、componentWillReceiveProps(nextProps)

      并不是只有在props发生改变的时候才会被调用,实际上只要是父组件的render函数被调用,render里面被渲染的子组件就会被更新,不管父组件传给子组件的props有没有被改变,都会触发子组件的componentWillReceiveProps过程,但是,this.setState方法的触发过程不会调用这个函数,因为这个函数适合根据新的props的值来计算出是不是要更新内部状态的state。

    2、shouldComponentUpdate(nextProps, nextState)

    这个函数的重要性,仅次于render,render函数决定了渲染什么,而shouldComponentUpdate决定了不需要渲染什么,都需要返回函数,这一过程可以提高性能,忽略掉没有必要重新渲染的过程

    3、componentWillUpdate和componentDidUpdate

    和装载过程不同,这里的componentDidUpdate,既可以在浏览器端执行,也可以在服务器端执行

    react中,触发render的有4条路径。

    以下假设shouldComponentUpdate都是按照默认返回true的方式。

     (1)首次渲染Initial Render

    (2)调用this.setState (并不是一次setState会触发一次render,React可能会合并操作,再一次性进行render)

    (3)父组件发生更新(一般就是props发生改变,但是就算props没有改变或者父子组件之间没有数据交换也会触发render)

    (4)调用this.forceUpdate

    注意如果在shouldComponentUpdate里面返回false可以提前退出更新路径。
    三、卸载过程

    实际中很少用到,这里只有一个componentWillUnmount,一般在componentDidMount里面注册的事件需要在这里删除。

     

    四、总结

    (一)命令式编程:jquery(自己寻找要操作的DOM元素,自己写要做的事情)

    (二)声明式编程:react(只需要在钩子函数中写东西即可,不需要执行钩子函数)

          这些钩子函数是本身就会执行的,我们重写了一部分,是为了在这个组件的某个时期做一些事情。

    (三)生命周期流程:

    1、第一次初始化渲染显示: ReactDOM.render()

         * constructor(): 创建对象初始化 state

         * componentWillMount() : 将要插入回调

         * render() : 用于插入虚拟 DOM 回调

         * componentDidMount() : 已经插入回调

    2每次更新 state: this.setState()

      * componentWillUpdate() : 将要更新回调

      * render() : 更新(重新渲染)

      * componentDidUpdate() : 已经更新回调

    3移除组件: ReactDOM.unmountComponentAtNode(containerDom)

      * componentWillUnmount() : 组件将要被移除回调

    (四)重要的勾子

    1、render(): 初始化渲染或更新渲染调用

    2、componentDidMount(): 开启监听, 发送 ajax 请求

    3、componentWillUnmount(): 做一些收尾工作, 如: 清理定时器

    五、示例

     <div id='container'></div>

        <script type="text/babel">

            class LifeCycle extends React.Component {

                constructor(props) {

                    super(props);

                    alert("Initial render");

                    alert("constructor");

                    this.state = {str: "hello"};

                }

                componentWillMount() {

                    alert("componentWillMount");

                }

                componentDidMount() {

                    alert("componentDidMount");

                }

                componentWillReceiveProps(nextProps) {

                    alert("componentWillReceiveProps");

                }

                shouldComponentUpdate() {

                    alert("shouldComponentUpdate");

                    return true;        // 记得要返回true

                }

     

                componentWillUpdate() {

                    alert("componentWillUpdate");

                }

                componentDidUpdate() {

                    alert("componentDidUpdate");

                }

                componentWillUnmount() {

                    alert("componentWillUnmount");

                }

                setTheState() {

                    let s = "hello";

                    if (this.state.str === s) {

                        s = "HELLO";

                    }

                    this.setState({

                        str: s

                    });

                }

                forceItUpdate() {

                    this.forceUpdate();

                }

                render() {

                    alert("render");

                    return(

                        <div>

                            <span>{"Props:"}<h2>{parseInt(this.props.num)}</h2></span>

                            <br />

                            <span>{"State:"}<h2>{this.state.str}</h2></span>

                        </div>

                    );

                }

            }

            class Container  extends React.Component {

                constructor(props) {

                    super(props);

                    this.state = {

                        num: Math.random() * 100

                    };

                }

                propsChange() {

                    this.setState({

                        num: Math.random() * 100

                    });

                }

                setLifeCycleState() {

                    this.refs.rLifeCycle.setTheState();

                }

                forceLifeCycleUpdate() {

                    this.refs.rLifeCycle.forceItUpdate();

                }

                unmountLifeCycle() {

                    // 这里卸载父组件也会导致卸载子组件

                    ReactDOM.unmountComponentAtNode(document.getElementById("container"));

                }

                parentForceUpdate() {

                    this.forceUpdate();

                }

                render() {

                    return (

                        <div>

                            <a href="javascript:;"  onClick={this.propsChange.bind(this)}>propsChange</a>

                               

                            <a href="javascript:;"  onClick={this.setLifeCycleState.bind(this)}>setState</a>

                               

                            <a href="javascript:;"  onClick={this.forceLifeCycleUpdate.bind(this)}>forceUpdate</a>

                               

                            <a href="javascript:;"  onClick={this.unmountLifeCycle.bind(this)}>unmount</a>

                               

                            <a href="javascript:;"  onClick={this.parentForceUpdate.bind(this)}>parentForceUpdateWithoutChange</a>

                            <LifeCycle ref="rLifeCycle" num={this.state.num}></LifeCycle>

                        </div>

                    );

                }

            }

            ReactDOM.render(

                <Container></Container>,

                document.getElementById('container')

            );

        </script>

     

  • 相关阅读:
    数全排列问题
    DNA repair问题
    分治问题
    贪心问题
    STL简单应用问题
    求一个数阶乘后位数问题
    《DSP using MATLAB》Problem 2.6
    《DSP using MATLAB》示例Example 10.4
    《DSP using MATLAB》Problem 2.5
    《DSP using MATLAB》Problem 2.4
  • 原文地址:https://www.cnblogs.com/lone5wolf/p/15831804.html
Copyright © 2020-2023  润新知