zoukankan      html  css  js  c++  java
  • React入门--------组件的生命周期

    • Mounting/组件挂载相关:

    componentWillMount

    componentDidMount

    • Updating/组件更新相关:

    componentWillReceiveProps

    shouldComponentUpdate

    componentWillUpdate

    componentDidUpdate

    • Unmounting/组件移除相关:

    componentWillUnmount

    一、Mounting/组件挂载相关

    componentWillMount

    在组件挂载之前执行,但仅执行一次,即使多次重复渲染改组件,或者改变了组件的state。若希望该回到能执行多次,可以使用ReactDOM.unmountComponentAtNode移除掉已有的组件,然后再重新render。

        var diva = document.getElementById('a');
        var divb = document.getElementById('b');
        var i=0;
        var Component1 = React.createClass({
            componentWillMount:function(){
                console.log(++i)
            },
            render: function() {
                console.log(Date.now());
                return <div name={this.props.name}>我只是一个安静的div</div>
            }
        });
        
      //触发componentWillMount,render ReactDOM.render(
    <Component1 />, diva );
      
      //未触发componentWillMount,触发render ReactDOM.render(
    <Component1 />, diva );
      //触发componentWillMount,render ReactDOM.render(
    <Component1 />, divb );
      //未触发componentWillMount,未触发render ReactDOM.render(
    <Component1 />, divb );

    componentDidMount

    在组件挂载之后执行,同componentWillMount一样,同一个组件重复渲染只执行一次,卸载组件后重新渲染可以重新触发一次。

    二、Updating/组件更新相关

    componentWillReceiveProps

    在组件接收到props的时间点之前调用,注意组件初始化渲染时不会调用。

        var i = 0;
        var div = document.getElementById('a'),
        var div2 = document.getElementById('b');
    
        var Component1 = React.createClass({
            componentWillReceiveProps: function(){
                console.log(i++)
            },
            clickCb: function() {
                React.render(
                    <Component1 />, div2
                );
            },
            render: function() {
                return <div onClick={this.clickCb}>点我给下一个div挂载组件</div>
            }
        });
    
        React.render(
            <Component1 />, div  //初始化不会触发componentWillReceiveProps
        );
        React.render(
                <Component1 />, div   //重复渲染会触发componentWillReceiveProps
        );
        React.unmountComponentAtNode(div);  //移除掉已有组件
        React.render(
            <Component1 />, div  //初始化不会触发componentWillReceiveProps
        );

    运行结果如下:

    该接口带有一个参数nextProps,可以利用它来获取新的props的值(this.props获取到的是当前的,也就是旧的props)

      var i = 0;
      var div = document.getElementById('a');
      var render = function(){
                React.render(
                        <Component1 i={i++} />, div
                );
            };
    
        var Component1 = React.createClass({
            componentWillReceiveProps: function(nextProps){
                console.log(this.props.i, nextProps.i)
            },
            render: function() {
                return <div onClick={render}>props.i的值是:{this.props.i}</div>
            }
        });
        render();

    运行结果如下

    shouldComponentUpdate

    该接口实际是在组件接收到了新的props或者新的state的时候会立即调用,然后通过返回值来决定是否要重新渲染当前的组件。

    接口带两个参数,第一个参数表示新的props,第二个参数表示新的state。

      var div = document.getElementById('a');
    
      var Component1 = React.createClass({
            getInitialState: function(){
                return { i : 0 }
            },
            shouldComponentUpdate: function(nextProps, nextState){
                console.log( this.state.i, nextState.i );
                return nextState.i > 3 ? true : false; //返回true才会渲染组件
            },
            clickCb: function(){
                this.setState({
                    i : this.state.i + 1
                })
            },
            render: function() {
                return <div onClick={this.clickCb}>state.i的值是:{this.state.i}</div>
            }
        });
        ReactDOM.render(
                <Component1 />, div
        );

    点击第四次之后才会渲染组件,在div里显示正确的新state.i

     

    componentWillUpdate

    同shouldComponentUpdate一样,在组件收到新的props或者state的时候会调用,而且也有着两个参数来获取新的props和state。

    不过本接口仅在shouldComponentUpdate执行并返回了true的时候才会被调用。

    在上一个代码实例中做点改动

     componentWillUpdate: function(nextProps, nextState){
                console.log( 'yoyoyo', this.state.i, nextState.i );
            },

    componentDidUpdate

    在组件更新,重新渲染完毕之后调用,它和componentWillUpdate一样有着两个参数来获取新的props和state

     var div = document.getElementById('a');
    
        var Component1 = React.createClass({
            getInitialState: function(){
                return { i : 0 }
            },
            shouldComponentUpdate: function(nextProps, nextState){
                console.log( this.state.i, nextState.i );
                return nextState.i > 3 ? true : false; //返回true才会执行componentWillUpdate并重新渲染组件
            },
            componentDidUpdate: function(nextProps, nextState){
                console.log( '已经渲染完毕咯', this.state.i, nextState.i );
            },
            componentWillUpdate: function(nextProps, nextState){
                console.log( '还没渲染哦', this.state.i, nextState.i );
            },
            clickCb: function(){
                this.setState({
                    i : this.state.i + 1
                })
            },
            render: function() {
                return <div onClick={this.clickCb}>state.i的值是:{this.state.i}</div>
            }
        });
        ReactDOM.render(
                <Component1 />, div
        );

    运行结果如下:

    三、Unmounting/组件移除相关:

     var div = document.getElementById('a');
     var div2 = document.getElementById('b');
    
     var Component1 = React.createClass({
        DOMArr : [],
        getInitialState: function(){
          return { i : 0 }
        },
        componentDidUpdate: function(nextProps, nextState){
          var dom = document.createElement('p');
          dom.innerText = this.state.i;
          div2.appendChild(dom);
          this.DOMArr.push(dom);
            },
        componentWillUnmount: function(){
          if(!this.DOMArr.length) return;
          var i = 0;
          while(i < this.DOMArr.length){console.log(i);
            div2.removeChild(this.DOMArr[i++]); //移除componentDidUpdate里添加过的DOM
          }
        },
        clickCb: function(){
          this.setState({
            i : this.state.i + 1
          })
        },
        render: function() {
          return <div onClick={this.clickCb}>state.i的值是:{this.state.i}</div>
        }
    });
    ReactDOM.render(
      <Component1 />, div
    );
    
    div2.addEventListener('click',function(){
      ReactDOM.unmountComponentAtNode(div) //点击div2则卸载掉第一个div里的组件
    }, false)

    运行结果如下:

    四、getDefaultProps和getInitialState

    getDefaultProps

    该方法是所有我们提及的方法中最先触发的,可以在该方法里return 一个对象来作为组件默认的props值(如果父组件传进来了props,以父组件为主),它只在组件初次挂载到页面上时触发,即使你重新挂载了组件。

    getInitialState

    用于给组件初始化state的值,调用该方法要求必须return 一个对象或者null,否则报错。该方法在组件每次实例化的时候都会触发。

    var diva = document.getElementsByTagName('div')[0],
                divb = document.getElementsByTagName('div')[1];
        var Component1 = React.createClass({
            getDefaultProps: function(){
                console.log('getDefaultProps');
                return { name : Date.now() }
            },
            getInitialState: function(){
                console.log('getInitialState');
                return null; //必须返回一个null或对象,否则会报错
            },
    
            render: function() {
                console.log(Date.now());
                return <div name={this.props.name}>我只是一个安静的div</div>
            }
        });
        ReactDOM.render(
                {/* 触发一次 getDefaultProps 和 getInitialState */}
                <Component1 />, diva
        );
        ReactDOM.render(
                {/* getDefaultProps 和 getInitialState都不触发 */}
                <Component1 />, diva
        );
        ReactDOM.unmountComponentAtNode(diva);
        ReactDOM.render(
                {/* 触发一次getInitialState */}
                <Component1 name="a"/>, diva
        );
        ReactDOM.render(
                {/* 触发一次getInitialState */}
                <Component1/>, divb
        );

    五、总结

    上面是9个周期接口,它们被触发的顺序?

     var Component1 = React.createClass({
            getDefaultProps: function(){
                console.log('getDefaultProps')
            },
            getInitialState: function(){
                console.log('getInitialState');
                return null
            },
            componentWillMount: function(){
                console.log('componentWillMount')
            },
            componentDidMount: function(){
                console.log('componentDidMount')
            },
            componentWillReceiveProps: function(){
                console.log('componentWillReceiveProps')
            },
            shouldComponentUpdate: function(){
                console.log('shouldComponentUpdate');
                return true;
            },
            componentWillUpdate: function(){
                console.log('componentWillUpdate')
            },
            componentDidUpdate: function(){
                console.log('componentDidUpdate')
            },
            componentWillUnmount: function(){
                console.log('componentWillUnmount')
            },
            render: function() {
                return <div>我只是一个安静的div</div>
            }
        });
        ReactDOM.render(
                <Component1 />, document.body
        );
        ReactDOM.render(
                <Component1 />, document.body
        );
        ReactDOM.unmountComponentAtNode(document.body)

    结果如下:

  • 相关阅读:
    react 中文文档案例三 (开关按钮)
    react 中文文档案例二 (头像时间)
    react 中文文档案例一 (倒计时)
    韩昊 20190905-2 博客作业
    韩昊 20190905-3 命令行和控制台编程
    bug的状态
    冒泡排序
    python简单实现自动化
    如何写好测试用例——慕课网
    快速搭建springboot项目
  • 原文地址:https://www.cnblogs.com/yddlvo/p/6198473.html
Copyright © 2011-2022 走看看