1. 程式人生 > >關於React的生命周期

關於React的生命周期

完成 清晰 base tco 行為 lin efault 解釋 以及

React 的主要思想是通過構建可復用組件來構建用戶界面。所謂組件其實就是 有限狀態機,通過狀態渲染對應的界面,且每個組件都有自己的生命周期,它規定了組件的狀態和方法需要在哪個階段進行改變和執行。有限狀態機(FSM),表示有限個狀態以及在這些狀態之間的轉移和動作等行為的模型。一般通過狀態、事件、轉換和動作來描述有限狀態機。React 通過管理狀態來實現對組件的管理。

雖然組件、狀態機、生命周期這三者都不是 React 獨創,如果熟悉 Web Components 標準,它與其中的自定義組件的生命周期的概念相似。但就目前而言,React 是將這三種概念結合地相對清晰流暢的界面庫。

React的生命周期包括三個階段,分別是:mounting階段, updating階段,unmounting階段。

一. MOUNTING

mountComponent 負責管理生命周期中的 getInitialState、componentWillMount、render 和 componentDidMount。

由於 getDefaultProps 是通過 Constructor 進行管理,因此也是整個生命周期中最先開始執行,而 mountComponent 只能望洋興嘆,無法調用到 getDefaultProps。這就解釋了為何 getDefaultProps 只執行1次的原因。

由於通過 ReactCompositeComponentBase 返回的是一個虛擬節點,因此需要利用 instantiateReactComponent 去得到實例,再使用 mountComponent 拿到結果作為當前自定義元素的結果。

首先通過 mountComponent 裝載組件,此時,將狀態設置為 MOUNTING,利用 getInitialState 獲取初始化 state,初始化更新隊列。若存在 componentWillMount,則執行;如果此時在 componentWillMount 中調用 setState,是不會觸發 reRender,而是進行 state 合並。到此時,已經完成 MOUNTING 的工作,更新狀態為 NULL,同時 state 也將執行更新操作,此刻在 render 中可以獲取更新後的 this.state 數據。

一. UPDATING階段

updateComponent 負責管理生命周期中的 componentWillReceiveProps、shouldComponentUpdate、componentWillUpdate、render 和 componentDidUpdate。首先通過 updateComponent 更新組件,如果前後元素不一致說明需要進行組件更新,此時將狀態設置為RECEIVING_PROPS。若存在 componentWillReceiveProps,則執行;如果此時在 componentWillReceiveProps 中調用 setState,是不會觸發 reRender,而是進行 state 合並。到此時,已經完成 RECEIVING_PROPS 工作,更新狀態為 NULL,同時 state 也將執行更新操作,此刻 this.state 可以獲取到更新後的數據。

註意:此時 this.state 雖然獲取到更新數據,但只能在內部源碼中使用,我們在開發時,若在 componentWillReceiveProps 中調用 setState,那麽在 componentWillReceiveProps、shouldComponentUpdate 和 componentWillUpdate 中還是無法獲取到更新後的 this.state,即此時訪問的this.state 仍然是未更新的數據,只有在 render 和 componentDidUpdate 中才能獲取到更新後的this.state。

調用 shouldComponentUpdate 判斷是否需要進行組件更新,如果存在 componentWillUpdate,則執行。

updateComponent 本質上也是通過 遞歸渲染 內容的,由於遞歸的特性,父組件的 componentWillUpdate 一定在其子組件的 componentWillUpdate 之前調用,而父組件的 componentDidUpdate 肯定在其子組件 componentDidUpdate 之後調用。當渲染完成之後,若存在 componentDidUpdate,則觸發,這就解釋了 componentWillReceiveProps – componentWillUpdate – render – componentDidUpdate 它們之間的執行順序。

三:UNMOUNTING

unmountComponent 負責管理生命周期中的 componentWillUnmount。

首先將狀態設置為 UNMOUNTING,若存在 componentWillUnmount,則執行;如果此時在 componentWillUnmount 中調用 setState,是不會觸發 reRender。更新狀態為 NULL,完成組件卸載操作。

setState 更新機制

當調用 setState 時,會對 state 以及 _pendingState 更新隊列進行合並操作,但其實真正更新 state 的幕後黑手是replaceState。replaceState 會先判斷當前狀態是否為 MOUNTING,如果不是即會調用 ReactUpdates.enqueueUpdate 執行更新。當狀態不為 MOUNTING 或 RECEIVING_PROPS 時,performUpdateIfNecessary 會獲取 _pendingElement、_pendingState、_pendingForceUpdate,並調用 updateComponent 進行組件更新。如果在 shouldComponentUpdate 或 componentWillUpdate 中調用 setState,此時的狀態已經從 RECEIVING_PROPS -> NULL,則 performUpdateIfNecessary 就會調用 updateComponent 進行組件更新,但 updateComponent 又會調用 shouldComponentUpdate 和 componentWillUpdate,因此造成循環調用,使得瀏覽器內存占滿後崩潰。

關於React的生命周期