zoukankan      html  css  js  c++  java
  • React生命周期浅析

    引言

    关于React的生命周期API,官网,有着详细说明。但在实际写代码的过程中,这些说明不能解决所有的疑惑。 所以我列举了一些编码中常见用例,供大家参考。

    示例代码如下

    
     
    /*
      use case
      1. mixin中重名生命周期方法
      2. 重复React.render同个组件
      3. 从 mount 到 unmount 再到 mount
      4. 子组件两次加载
      5. 父组件update
      6. 改变子组件的包裹
    */
    
    var IamMixinObject = {
      componentDidMount: function(){
        console.log('mixin里的componentDidMount');
      }
    };
    
    var SonClass = React.createClass({
      mixins: [IamMixinObject],
      getDefaultProps:function(){
        console.log("getDefaultProps");
      },
      componentWillReceiveProps :function(){
        console.log("componentWillReceiveProps");
      },
      getInitialState:function(){
        console.log("getInitialState");
        return {};
      },
      componentWillMount:function(){
        console.log("componentWillMount");
      },
      componentWillUpdate:function(){
        console.log("componentWillUpdate");
      },
      shouldComponentUpdate:function(){
        console.log("shouldComponentUpdate");
        return true;
      },
      render: function(){
        console.log("render");
        return null;
      },
      componentDidUpdate: function(){
        console.log('componentDidUpdate');
      },
      componentDidMount: function(){
        console.log('componentDidMount');
      },
      componentWillUnmount: function(){
        console.log('componentWillUnmount');
      }
    });
    
    
    // 1. mixin中重名生命周期方法
    React.render(<SonClass />, document.getElementById("forTest"));
    /*
      mixin里的componentDidMount 会先于 componentDidMount输出。
      其实,mixin中和组件同名的生命周期方法,都是mixin中先执行。
    */
    
    
    // 2. 重复React.render同个组件
    React.render(<SonClass />, document.getElementById("forTest"));
    React.render(<SonClass />, document.getElementById("forTest"));
    /*
      输出:
      getDefaultProps
      getInitialState
      componentWillMount
      render
      mixin里的componentDidMount
      componentDidMount
    
      componentWillReceiveProps
      shouldComponentUpdate
      componentWillUpdate
      render
      componentDidUpdate 
      总结:
      第二次mount同个render组件,相当于改变 组件props。
    */
    
    // 3. 从 mount 到 unmount 再到 mount
    React.render(<SonClass />, document.getElementById("forTest"));
    React.unmountComponentAtNode(document.getElementById("forTest"));
    React.render(<SonClass />, document.getElementById("forTest"));
    /*
      输出:
      getDefaultProps
      getInitialState
      componentWillMount
      render
      mixin里的componentDidMount
      componentDidMount
      componentWillUnmount
    
      getInitialState
      componentWillMount
      render
      mixin里的componentDidMount
      componentDidMount
      总结:
      unmount的时候,确实调用了componentWillUnmount方法,第二次mount的时候,并没有执行getDefaultProps方法。
      是因为,getDefaultProps Invoked once and cached when the class is created。
      它在组件类创建的时候被调用一次,其返回值会被缓存。
    */
    
    
    // 4. 子组件两次装载
    var FatherClass = React.createClass({
      render:function(){
    
        return (
          <div>
            <SonClass />
            <SonClass />      
          </div>
        )
      }
    });
    React.render(<FatherClass />, document.getElementById("forTest"));
    /*
      输出:
      getDefaultProps
      getInitialState
      componentWillMount
      render
      getInitialState
      componentWillMount
      render
    
      mixin里的componentDidMount
      componentDidMount
      mixin里的componentDidMount
      componentDidMount
      总结:
      发现两次componentDidMount是后面连续触发。
      这里涉及到React的batchUpdate机制,需要另一篇文章详解。
      大概机制是,
      因为setState是异步的。
      它把变化存入一个临时队列,渲染完新的内容后才调用所有 componentDidUpdate或componentDidMount。
    
    */
    
    // 5. 父组件update
    var FatherClass = React.createClass({
      getInitialState:function(){
        
        return {
          changeFlag:false
        };
      },
      changeSon:function(){
        var changeFlag = this.state.changeFlag;
        this.setState({
          changeFlag: !changeFlag
        });
      },
      render:function(){
        return (
          <div onClick={this.changeSon} >
            <SonClass />                
          </div>
        )
      }
    });
    React.render(<FatherClass />, document.getElementById("forTest"));
    /*
      输出:
      getDefaultProps
      getInitialState
      componentWillMount
      render
      mixin里的componentDidMount
      componentDidMount
    
      componentWillReceiveProps  
      shouldComponentUpdate
      componentWillUpdate
      render
      componentDidUpdate
      总结:
      父组件setState了,对于子组件是setProps了
    */
    
    // 6. 改变子组件的包裹
    var FatherClass = React.createClass({
      getInitialState:function(){
        
        return {
          changeFlag:false
        };
      },
      changeSon:function(){
        var changeFlag = this.state.changeFlag;
        this.setState({
          changeFlag: !changeFlag
        });
      },
      render:function(){
        var changeFlag = this.state.changeFlag; 
        var Son = changeFlag ? <SonClass /> : <div>new son<SonClass /></div>
    
        return (
          <div onClick={this.changeSon} >
            父组件在此          
            {
                Son
            }        
          </div>
        )
      }
    });
    React.render(<FatherClass />, document.getElementById("forTest"));
    /*
      输出:
      getDefaultProps
      getInitialState
      componentWillMount
      render
      mixin里的componentDidMount
      componentDidMount
    
      componentWillUnmount
    
      getInitialState
      componentWillMount
      render
      mixin里的componentDidMount
      componentDidMount
      总结:
      父组件setState改变了子组件的包裹,子组件相当于重新mount
    
    */
                              
    
    
    
  • 相关阅读:
    微信开发-微信红包实例;
    微信支付-商户调用支付接口失败,已完成交易接口升级的用户应使用新接口进行交易;
    JS 获取当前时间
    微信支付-退款之CURL 52
    Binniabia is what?
    WIN7 自动同步服务器上备份文件
    WIN7 自动同步服务器上备份文件
    CSS之clearfix清除浮动
    解决IOS iframe不滚动问题
    CSS文字不换行,溢出省略
  • 原文地址:https://www.cnblogs.com/samwu/p/4913534.html
Copyright © 2011-2022 走看看