React 教程第九篇 —— 生命週期

生命週期

React 是一個由虛擬 DOM 渲染成真實 DOM 的過程,這個過程稱爲組件的生命週期。React 把這個週期劃分爲三個階段,每一個階段都提供了 will 和 did 兩種處理方式,will 是指發生前,did 是指發生後。javascript

  • Mounting:組件渲染過程html

    • componentWillMount()
    • componentDidMount()
  • Updating:組件更新過程java

    • componentWillReceiveProps(nextProps)
    • shouldComponentUpdate(nextProps, nextState)
    • componentWillUpdate(object nextProps, object nextState)
    • componentDidUpdate(object prevProps, object prevState)
  • Unmounting:組件移除過程react

    • componentWillUnmount()
    • 這個階段沒有對應的 did 方法

Mounting

指首次渲染或者組件從 DOM 中移除後再次從新渲染,後者場景不會執行 getDefaultPropsgit

執行順序

  1. getDefaultProps
  2. getInitialState
  3. componentWillMount
  4. render
  5. componentDidMount

componentWillMount

該方法在 render 以前被調用,也就是說在這個方法當中沒法獲取到真實的 DOM 元素。
首次渲染前和當 state 發生改變時再次渲染前觸發該方法。github

componentDidMount

該方法是在 render 以後被調用,也就是這個方法能夠直接獲取到真實的 DOM 元素。
首次渲染後和當 state 發生改變再次渲染後觸發該方法。優化

var MountingComponent = React.createClass({
    componentWillMount: function(){
        console.log(this.refs.h1) // undefined
    },
    componentDidMount: function(){
        console.log(this.refs.h1) // h1 對象
    },
    render: function(){
        return <h1 ref="h1">Lifecycle-Mounting</h1>;
    }                
})
ReactDOM.render(<MountingComponent />, document.getElementById('div1'));

Updating

當改變組件的 props 或 state 時候會觸發this

執行順序

  1. componentWillReceiveProps
  2. shouldComponentUpdate
  3. componentWillUpdate
  4. render
  5. componentDidUpdate

componentWillReceiveProps

在組件接收到一個新的prop時被調用。這個方法在初始化render時不會被調用。
方法接受一個參數
newProps: 爲更新後的 props
注:props 不能手動改變,正常場景是當前組件被當子組件調用,而後在父組件中改變該組件的 propscode

shouldComponentUpdate

組件掛載以後,每次調用setState後都會調用shouldComponentUpdate判斷是否須要從新渲染組件。默認返回true,須要從新render。在比較複雜的應用裏,有一些數據的改變並不影響界面展現,能夠在這裏作判斷,優化渲染效率。
方法接受兩個參數
newProps:已更新的 props
newState:已更新的 state
方法必需要返回 boolen,返回 true 則執行後面的 componentWillUpdate、render、componentDidUpdate。反之則不執行。component

componentWillUpdate

在組件接收到新的props或者state但尚未render時被調用。在初始化時不會被調用。
方法接受兩個參數
nextProps:將要更新的 props
nextState:將要更新的 state

componentDidUpdate

在組件完成更新後當即調用。在初始化時不會被調用。
方法接受兩個參數
prevProps:更新前的 props
nextState:更新前的 state

var UpdatingComponent = React.createClass({
    getInitialState: function() {
        return {
            data:0
        };
    },           
    setNewNumber: function() {
        //當 state 發生改變的時候,state 對應的組件會從新掛載
        //會觸發 componentWillUpdate、componentDidUpdate
        this.setState({data: this.state.data + 1})
    },
    //參數 newProps:已更新的 props
    componentWillReceiveProps:function(newProps) {
        console.log('Component WILL RECEIVE PROPS!', newProps)
    },        
    //參數 newProps:已更新的 props
    //參數 newState:已更新的 state  
    //必需要返回 boolen,true 則執行componentWillUpdate、render、componentDidUpdate。反之則不執行。
    shouldComponentUpdate: function(newProps, newState){
        console.log('shouldComponentUpdate',newProps, newState);
        return (newState.data > 0 && newState.data % 2 == 0);
    },                          
    //參數 nextProps:將要更新的 props
    //參數 nextState:將要更新的 state
    componentWillUpdate: function(nextProps, nextState){
        console.log(nextProps, nextState, this.refs.p1)
    },
    //參數 prevProps:更新前的 props
    //參數 nextState:更新前的 state                
    componentDidUpdate: function(prevProps, prevState){
        console.log(prevProps, prevState) 
    },
    render: function(){
        return (
            <div>
                <button onClick={this.setNewNumber}>INCREMENT</button>
                <h3>{this.state.data}</h3>
            </div>
        );
    }                
})
ReactDOM.render(<UpdatingComponent/>, document.getElementById('div2'));

Unmounting

在組件從 DOM 中移除的時候馬上被調用,這個階段沒有對應的 did 方法

componentWillUnmount

方法適用在父子組件的結構中,當某個條件符合的場景下,該子組件會被渲染

從新渲染的執行順序

  1. getInitialState
  2. componentWillMount
  3. render
  4. componentDidMount
var ChildrenComponent = React.createClass({
    componentWillUnmount: function(){
        console.log('componentWillUnmount');
    },
    render: function(){
        return <h3>{this.props.myNumber}</h3>
    }
})

var UnmountingComponent = React.createClass({
    getInitialState: function() {
        return {
            data:0
        };
    },
    setNewNumber: function() {
        this.setState({data: this.state.data + 1})
    },
    render: function () {
        var content;
        //當條件不符合時 ChildrenComponent 會被移除,而後會觸發方組件的 componentWillUnmount 方法
        //當條件從新符合時,會從新渲染組件 ChildrenComponent
        if(this.state.data % 2 == 0){
            content = <ChildrenComponent myNumber = {this.state.data}></ChildrenComponent>;
        } else {
            content = <h3>{this.state.data}</h3>;
        }
        return (
            <div>
                <button onClick = {this.setNewNumber}>INCREMENT</button>
                {content}
            </div>
        );
    }
})

ReactDOM.render(<UnmountingComponent/>, document.getElementById('div3'));

效果預覽

相關文章
相關標籤/搜索