1. 程式人生 > >react 生命週期的學習

react 生命週期的學習

寫給自己看的一些東西

生命週期函式使用時必須使用已經定義好的名字,如componentWillMount()等,表示所編寫的命令在這個階段執行。如componentWillMount(),表示編寫的命令在元件將要載入時執行。其函式的位置不重要,在哪兒都是會按照理應當的順序執行。
但是在不同js指令碼中的同一個函式載入順序不同,index中componentWillMount()是最先載入的,componentDidMount()是最後載入的。也就是說,index.js是一個大框架,內部是各個元件,按照這個套用順序進行處理。

react生命週期
React元件的生命週期分為三個過程:

  1. 初始化過程(Mount):第一次把元件渲染到DOM樹的過程;
  2. 執行過程(Update):元件進行渲染更新的過程,包括狀態改變和屬性改變
  3. 解除安裝過程(Unmount):元件從DOM樹中刪除的過程。

初始化

是元件第一次繪製階段,在這裡完成了元件的載入和初始化;

  • getDefaultProps:
    在元件建立之前,會先呼叫getDefaultProps(),初始化元件屬性的預設值,只調用一次,嚴格地來說,這不是元件的生命週期的一部分。
  • getInitialState:
    在元件被建立並載入後,首先呼叫getInitialState(),來初始化元件的狀態。
  • componentWillMount():
    準備載入元件,會呼叫componentWillMount(),其原型如下:
void componentWillMount()

這個函式呼叫是在元件建立,並初始化了狀態之後,在第一次繪製render()之前。 可以在這裡做一些業務初始化操作,也可以設定元件狀態。 這個函式在整個生命週期中只被呼叫一次。因為componentWillMount是在render之前執行,所以在這個方法中setState不會發生重新渲染(re-render);
- 這是服務端渲染(server render)中唯一呼叫的鉤子(hook);
- 通常情況下,推薦用constructor()方法代替;

  • render():
    渲染元件時,唯一的一定不能省略的函式,必須有返回值,返回null或false表示不渲染任何DOM元素。它是一個僅僅用於渲染的純函式,返回值完全取決於this.state和this.props,不能在函式中修改props、state、拉取資料等具有副作用的操作。
  • componentDidMount():
    在render完成後 元件完成更新渲染到頁面時觸發,會呼叫componentDidMount(),通知元件已經載入完成。函式原型如下:
void componentDidMount()

這個函式呼叫的時候,其虛擬 DOM 已經構建完成,可以在這個函式開始獲取其中的元素或者子元件了。 需要注意的是,RN 框架是先呼叫子元件的componentDidMount(),然後呼叫父元件的函式。從這個函式開始,就可以和 JS 其他框架互動了,例如設定計時setTimeout或者setInterval,或者發起網路請求。這個函式也是隻被呼叫一次。這個函式之後,就進入了穩定執行狀態,等待事件觸發。
- 這個方法會在元件裝載(mounting)(插入樹)後之後立即執行;
- 這裡可以對DOM進行操作,這個函式之後ref變成實際的DOM
- 這裡可以載入伺服器資料,並且如果使用了redux之類的資料服務,
- 這裡可以出發載入伺服器資料的action;
- 這裡可以使用setState()方法觸發重新渲染(re-render);

執行過程:

屬性改變:
  • componentWillReceiveProps(nextProps):
    在已經掛在的元件(mounted component)接收到新props時觸發;簡單的說是從除了第一次生命週期(componentWillMount -> render -> componentDidMount)之後的生命週期出發,其原型如下:
void componentWillReceiveProps(	object nextProps)

輸入引數nextProps是即將被設定的屬性,舊的屬性還是可以通過this.props來獲取。在這個回撥函式裡面,你可以根據屬性的變化(判斷this.props和nextProps),通過呼叫this.setState()來更新你的元件狀態,這裡呼叫更新狀態是安全的,並不會觸發額外的render()呼叫。如下:

componentWillReceiveProps: function(nextProps) {
	this.setState({
		likesIncreasing: nextProps.likeCount > this.props.likeCount
	});
}

注意:
1、 React可能會在porps傳入時即使沒有發生改變的時候也發生重新渲染, 所以如果你想自己處理改變,請確保比較props當前值和下一次值;
2、如果你只是呼叫this.setState()而不是從外部傳入props, 那麼不會觸發componentWillReceiveProps(nextProps)函式;這就意味著: this.setState()方法不會觸發componentWillReceiveProps(), props的改變或者props沒有改變才會觸發這個方法;

狀態改變:
  • shouldComponentUpdate(nextProps, nextState):
    接收到新props或state時,或者說在componentWillReceiveProps(nextProps)後觸發
    函式原型如下:
boolean shouldComponentUpdate(object nextProps, object nextState)

輸入引數nextProps和上面的componentWillReceiveProps函式一樣,nextState表示元件即將更新的狀態值。這個函式的返回值決定是否需要更新元件,如果true表示需要更新,繼續走後面的更新流程。否者,則不更新,直接進入等待狀態。
預設情況下,這個函式永遠返回true用來保證資料變化的時候 UI 能夠同步更新。在大型專案中,你可以自己過載這個函式,通過檢查變化前後屬性和狀態,來決定 UI 是否需要更新,能有效提高應用效能。
注意
1、這個方法在首次渲染時或者forceUpdate()時不會觸發;
2、這個方法如果返回false, 那麼props或state發生改變的時候會阻止子元件發生重新渲染;
3、目前,如果shouldComponentUpdate(nextProps, nextState)返回false, 那麼componentWillUpdate(nextProps, nextState), render(), componentDidUpdate()都不會被觸發;
4、未來,React可能把shouldComponentUpdate()當做一個小提示(hint)而不是一個指令(strict directive),並且它返回false仍然可能觸發元件重新渲染(re-render);

  • componentWillUpdate(nextProps, nextState):
    如果元件狀態或者屬性改變,並且上面的shouldComponentUpdate(…)返回為true,就會開始準更新元件,並呼叫componentWillUpdate(),其函式原型如下:
void componentWillUpdate(object nextProps, object nextState)

輸入引數與shouldComponentUpdate一樣,在這個回撥中,可以做一些在更新介面之前要做的事情。需要特別注意的是,在這個函式裡面,你就不能使用this.setState來修改狀態。 這個函式呼叫之後,就會把nextProps和nextState分別設定到this.props和this.state中。緊接著這個函式,就會呼叫render()來更新介面了。
注意
1、千萬不要在這個函式中呼叫this.setState()方法.;
2、如果確實需要響應props的改變,那麼你可以在componentWillReceiveProps(nextProps)中做響應操作;
3、如果shouldComponentUpdate(nextProps, nextState) 返回false,那麼componentWillUpdate()不會被觸發;

  • componentDidUpdate(prevProps, prevState):
    呼叫了render()更新完成介面之後,會呼叫componentDidUpdate()來得到通知,其函式原型如下:
void componentDidUpdate(object prevProps, object prevState)

因為到這裡已經完成了屬性和狀態的更新了,此函式的輸入引數變成了prevProps和prevState。
1、該方法不會再元件初始化時觸發;
2、使用這個方法可以對元件中的DOM進行操作;
3、只要你比較了this.props和nextProps,你想要發出網路請求(nextwork requests)時就可以發出, 當然你也可以不發出網路請求;
注意:
如果shouldComponentUpdate(nextProps, nextState)返回false, 那麼componentDidUpdate(prevProps, prevState)不會被觸發;

解除安裝過程

  • componentWillUnmount():
    當元件要被從介面上移除的時候,就會呼叫componentWillUnmount(),其函式原型如下:
void componentWillUnmount()

這個方法可以讓你處理一些必要的清理操作,比如無效的timers、interval,或者取消網路請求, 或者清理任何在componentDidMount()中建立的DOM元素(elements);

總結

  • 元件初始化
    原因 :元件第一次建立
    觸發:componentWillMount -> render ->componentDidMount
  • 元件更新 – props change
    原因:props發生改變
    觸發componentWillReceiveProps -> shouldComponentUpdate -> componentWillUpdate -> componentDidUpdate
  • 元件更新 – state change
    原因:this.setState()使state發生改變
    觸發:shoudlComponentUpdate -> componentWillUpdate ->componentDidUpdate
  • 元件解除安裝或銷燬
    原因:元件解除安裝或銷燬
    觸發:componentWillUnmount