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)

結果如下:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM