文章出處

引言

關于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

*/
                          

文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()