1. 程式人生 > >【ReactJS】通過一個例子學習React元件的生命週期

【ReactJS】通過一個例子學習React元件的生命週期

原始碼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>React-props</title>
    <script src
="https://cdn.bootcss.com/react/15.4.2/react.min.js">
</script> <script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script> <script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script> </head> <body> <div id="demo"
>
</div> <script type="text/babel"> var AddCount=React.createClass({ getInitialState:function(){ console.log('1...getInitialSate'); return {count:1}; }, componentWillMount:function(){ console.log('2...componentWillMount'
); }, componentDidMount:function(){ console.log('3...componentDidMount'); }, componentWillUpdate:function(){ console.log('4...componentWillUpdate'); }, componentDidUpdate:function(){ console.log('4...componentDidUpdate'); }, handleClick:function(event){ this.setState({count:this.state.count+1}) }, render:function(){ return( <p> {this.state.count}<br/> <button onClick={this.handleClick}>Add</button> </p> ) } }) ReactDOM.render( <AddCount/>, document.getElementById("demo") );
</script> </body> </html>

效果圖

這裡寫圖片描述

元件的生命週期

  為了理解 React 的工作過程,我們就必須要了解 React 元件的生命週期,如同人有生老病死,自然界有日月更替,每個元件在網頁中也會被建立、更新和刪除,如同有生命的機體一樣。

  React 嚴格定義了元件的生命週期,生命週期可能會經歷如下三個過程:

  • 裝載過程(Mount),也就是把元件第一次在DOM樹中渲染的過程;
  • 更新過程(Update),當元件被重新渲染的過程;
  • 解除安裝過程(Unmount),元件從DOM中刪除的過程;
    三種不同的過程,React 庫會依次呼叫元件的一些成員函式,這些函式稱為生命週期函式。所以,要定製一個React元件,實際上就是定製這些生命週期函式。

裝載過程

當元件第一次被渲染的時候,依次呼叫的函式是如下這些:

  • constructor
  • getInitialState
  • getDefaultProps
  • componentWillMount
  • render
  • componentDidMount

constructor、getInitialState、getDefaultProps和render我在 深入理解prop、state與render函式 有記載過,若不懂可以跳轉檢視。

  這裡主要說下 componentWillMount 和 componentDidMount。

  在裝載過程中,componentWillMount 會在呼叫 render 函式之前被呼叫,componentDidMount 會在呼叫 render 函式之後被呼叫,這兩個函式就像是 render 函式的前哨和後衛,一前一後,把 render 函式夾住,正好分別做 render 前後必要的工作。

  不過,我們通常不用定義 componentWillMount 函式,顧名思義,componentWillMount 發生在“將要裝載”的時候,這個時候沒有任何渲染出來的結果,即使呼叫 this.setState 修改狀態也不會引發重新繪製,一切都遲了。換句話說,可以在這個 componentWillMount 中做的事情,都可以提前到 constructor 中間去做,可以認為這個函式存在的主要目的就是為了和 componentDidMount 對稱。

  而 componentWillMount 的這個兄弟 componentDidMount 作用就大了。

  需要注意的是,render 函式被呼叫完之後,componentDidMount 函式並不是會被立刻呼叫,componentDidMount 被呼叫的時候,render 函式返回的東西已經引發了渲染,元件已經被“裝載”到了DOM樹上。
  
  之所以會有上面的現象,是因為 render 函式本身並不往DOM樹上渲染或者裝載內容,它只是返回一個JSX表示的物件,然後由 React 庫來根據返回物件決定如何渲染。所以,只有React庫呼叫n個元件的render函式之後,才有可能完成裝載,這時候才會依次呼叫各個元件的 componentDidMount 函式作為裝載過程的收尾。

更新過程

更新過程會依次呼叫下面的生命週期函式,其中render函式和裝載過程一樣,沒有差別。

  • componentWillReceiveProps
  • shouldComponentUpdate
  • componentWillUpdate
  • render
  • componentDidUpdate

除了render函式,shouldComponentUpdate可能是React元件生命週期中最重要的一個函數了。

  說 render 函式重要,是因為 render 函式決定了該渲染什麼,而說 shouldComponentUpdate 函式重要,是因為它決定了一個元件什麼時候不需要渲染。

  render 和 shouldComponentUpdate 函式,也是React生命週期函式中唯二兩個要求有返回結果的函式。render 函式的返回結果將用於構造DOM物件,而 shouldComponentUpdate 函式返回一個布林值,告訴 React 庫這個元件在這次更新過程中是否要繼續。

  在更新過程中,React 庫首先呼叫 shouldComponentUpdate 函式,如果這個函式返回 true,那就會繼續更新過程,接下來呼叫 render 函式;反之,如果得到一個 false,那就立刻停止更新過程,也就不會引發後續的渲染了。

  說 shouldComponentUpdate 重要,就是因為只要使用恰當,他就能夠大大提高 React 元件的效能,雖然 React 的渲染效能已經很不錯了,但是,不管渲染有多快,如果發現沒必要的重新渲染,那就乾脆不用渲染好了,速度會更快。

  我們知道 render 函式應該是一個純函式,這個純函式的邏輯輸入就是元件的 props 和 state。所以,shouldComponentUpdate 的引數就是接下來的 props 和 state 值。如果我們要定義 shouldComponentUpdate,那就根據這兩個引數,外加 this.props 和 this.state 來判斷出是返回 true 還是返回 false。

解除安裝過程

  React元件的解除安裝過程只涉及一個函式 componentWillUnmount,當 React 元件要從DOM樹上刪除掉之前,對應的 componentWillUnmount 函式會被呼叫,所以這個函式適合做一些清理性的工作。

  和裝載過程與更新過程不一樣,這個函式沒有配對的 Did 函式,就一個函式,因為解除安裝完就完了,沒有“解除安裝完再做的事情”。

  每當元件使用完成,這個元件就必須從DOM中銷燬,此時該方法就會被自動呼叫。當我們在元件中使用了setInterval,那我們就需要在這個方法中呼叫clearTimeout。