1. 程式人生 > >React元件的生命週期及執行順序

React元件的生命週期及執行順序

本文原創地址連結:http://blog.csdn.net/zhou_xiao_cheng/article/details/52461414,未經博主允許不得轉載。
覺得學習React,瞭解它的生命週期是很重要的。這次,讓我們一起來看看,到底什麼是元件的生命週期?
按照我的理解,元件生命週期一般指的是:元件從被建立到它消亡的過程,因此,元件生命週期方法就是指:在這個過程(建立 ->消亡)中,在一個特定的點會被呼叫的方法。
簡單點說,我們可以把元件的生命週期看作是一根平鋪於桌面的線,這根線上繫了很多鉤子,鉤子都鉤著一個方法,當從線的一頭提起這根線,那麼鉤子(連同它們上面的方法)都會被逐一提起,這個過程,就是React元件生命週期方法被逐一呼叫的過程了,至於呼叫的順序,接下來會講到。
俗話說得好,凡事都有例外,如果你只是單純地想用一個無狀態的JavaScript函式(沒有state

)來定義一個React元件,如下:

function StatelessFunc(props) {
  return <div>{props.name}</div>;
}
ReactDOM.render(<StatelessFunc name="zhou xiao cheng" />, document.getElementById('app'));

那麼,這個元件就是沒有生命週期的,因為它只是在簡單地做函式輸出。但你可以在該元件上設定你的defaultProps(例如:StatelessFunc.defaultProps = { name: 'zhou' }

)及propTypes,官方建議我們多使用這樣的無狀態函式來作為元件,以便將來可能會用避免不必要的檢查和記憶體分配的方式來對這些元件進行優化。

生命週期方法介紹

對於一個包含著生命週期的元件,有以下可選的生命週期方法:

  1. componentWillMount()
    僅在render()方法前被呼叫一次,如果在該方法中呼叫了setState方法去改變元件的狀態值,那麼呼叫render()後,將會直接看到改變過了的狀態值,並且不論狀態值怎麼改變,componentWillMount()都不會再被呼叫。

    class Demo extends React.Component {
      constructor() {
        super
    () this.state = { value: 0 } } componentWillMount() { this.setState({ value: this.state.value + 1 }) console.log('123') } render() { return ( <div>{this.state.value}</div> ) } } ReactDOM.render(<Demo />, document.getElementById('app')) ReactDOM.render(<Demo />, document.getElementById('app'))
  2. componentDidMount()
    僅在render()方法後被立即呼叫一次(客戶端),相對於父元件而言,該方法在子元件中會先被呼叫。如果需要使用一些JaveScript框架或者類似於setInterval()這樣的方法,建議在該方法內使用。

  3. ShouldComponentUpdate(object nextProps, object nextState)
    在初始渲染呼叫render()方法時不會被呼叫,後面在接受到新的state或者props時,在render()方法前被呼叫。為防止一些潛在的bug,該方法預設總是返回true。如果你確定state及props改變後不需要渲染元件,那麼也可以指定返回false,需要注意的是,這樣的結果會導致後面的render()、componentWillUpdate()、componentDidUpdate()都不會被呼叫。

  4. componentWillReceiveProps(object nextProps)
    在初始渲染呼叫render()方法時不會被呼叫,當接收到一個新的props時,該方法被呼叫。我們都知道,如果改變一個狀態的值,則會觸發render()方法,所以可以在這個方法裡呼叫setState()方法去改變一個狀態的值,當該方法接收到新的props時,setState()就可以避免一次額外的render()了。
    在這個方法裡,尤其需要注意一點,就是接收到新的props一定會觸發render()方法,但是render()方法被觸發不一定是因為接收到了新的props(具體請戳這裡)。如下:

    class Demo extends React.Component {
      componentWillReceiveProps(nextProps) {
        console.log('componentWillReceiveProps is invoked', nextProps.val.name)
      }
      render() {
        return (
          <div>{this.state.value}</div>
        )
      }
    }
    var data = {
      name: 'zhou xiao cheng'
    }
    ReactDOM.render(<Demo val={data} />, document.getElementById('app'))
    ReactDOM.render(<Demo val={data} />, document.getElementById('app'))
    ReactDOM.render(<Demo val={data} />, document.getElementById('app'))

    在上面的程式碼中,props沒有發生改變,但render()方法卻被呼叫了兩次。

  5. componentWillUpdate(object nextProps, object nextState)
    在初始渲染呼叫render()方法時不會被呼叫,當接收到新的props及state時,在render()方法之前被呼叫。

  6. componentDidUpdate(object prevProps, object prevState)
    在初始渲染呼叫render()方法時不會被呼叫,當元件更新被重新整理到DOM之後被立即呼叫。

  7. componentWillUnmount()
    在元件從DOM上解除安裝前被呼叫,在這個方法裡面,我們主要是完成一些清除操作,比如說清除掉一些過時了的定時器等。

元件規範介紹

除了上面的7個可選的生命週期方法,我們可以將剩下的一些方法稱之為元件規範。接下來,我們將會對一些較為常用的元件規範進行介紹。

  1. render()
    對於一個元件而言,render()方法是必須的,通常,在這個方法裡面,我們都會返回一個元素(如:<div></div>),但同樣也可以返回falsenull,這意味著我們沒有任何東西需要渲染。

  2. getInitialState()
    在ES6的語法中,這個方法可以寫成下面這樣(將其寫在建構函式中,this.state的值就是狀態初始值),其效果是一樣的:

    class Demo extends React.Component {
      constructor() {
        super()
        this.state = {
          key: value
        }
    }
  3. getDefaultProps()
    ES6的語法中,寫法如下:

    Demo.defaultProps = {key: value}

    ES7中,還可以寫成這樣(但需要配合Babel轉換器進行使用):

    class Demo extends React.Component {
      static defaultProps = {
        key: value
      }
    }
  4. propTypes
    ES6的語法中,寫法如下(想了解更多propTypes請戳官方propTypes介紹):

    Demo.propTypes = {
      requiredFunc: React.PropTypes.func.isRequired
    }

    同樣,在ES7中,可以寫成下面這樣:

    class Demo extends React.Component {
      static propTypes = {
        requiredFunc: React.PropTypes.func.isRequired
      }
    }
  5. static
    ES6語法中,static關鍵字則允許我們定義一個在元件類上能夠呼叫的靜態方法和屬性:

    class Demo extends React.Component {
      static method = function(){
        //doSomething
      }
      static propTypes = {
        requiredFunc: React.PropTypes.func.isRequired
      }
    }
    //呼叫靜態方法
    Demo.method()
    //呼叫屬性
    Demo.propTypes

呼叫順序及次數

如果你能理解上面所敘述的,那麼,就不難得出下面的結論啦~~~

  1. getDefaultProps(),呼叫1次
  2. getInitialState(),呼叫1次
  3. componentWillMount(),呼叫1次
  4. render(),呼叫>=1次
  5. componentDidMount():僅客戶端,呼叫1次
  6. componentWillReceiveProps(object nextProps),呼叫>=0次
  7. ShouldComponentUpdate(object nextProps, object nextState),呼叫>=0次
  8. componentWillUpdate(object nextProps, object nextState),呼叫>=0次
  9. render(),呼叫>=1次
  10. componentDidUpdate(object prevProps, object prevState),呼叫>=0次
  11. componentWillUnmount(),呼叫1次

好了,這次就寫到這了,望與各君共勉。