在上一篇文章《React原始碼解析(一):元件的實現與掛載》中,我們闡述了React元件的實現和掛載。現在我們來一起探究元件的生命週期。
我們已經知道,只有在掛載流程開始後,才會觸發元件的生命週期,生成ReactElement
型別的js物件,通過解析元件物件內部所攜帶的資訊,獲得對應的HTML資訊,插入指定的DOM容器中,最終完成檢視的渲染。那麼元件的生命週期在這一過程中是如何觸發的呢?
其實研究元件的宣告週期,就是更深入的研究元件的掛載過程。
元件的生命週期
在上一篇文章的最後,我們知道ReactDOM.render()
方法根據傳入的引數不同,在內部通過工廠方法生成四種不同型別的封裝元件:
- ReactEmptyComponent
- ReactTextComponent
- ReactDOMComponent
- ReactCompositeComponent
在執行掛載流程時,通過執行每種封裝元件內部的mountComponent
方法觸發生命週期,但顯然生命週期只在React自定義元件中存在,也就是ReactCompositeComponent
。因為其他三種元件是不存在生命週期的,所以我們先來分析下相對容易的不存在生命週期的三種內部元件。
1.ReactEmptyComponent
通過ReactEmptyComponent.create()
方法建立,該方法最終呼叫的是ReactDOMEmptyComponent
方法,看下原始碼:
因為元件為空,所以幾乎所有引數設定為null,也無關生命週期,只有元件的掛載和解除安裝。在關鍵方法mountComponent
中,我們看到最終返回的是形如<!-->
的HTML,也就是空,因此插入真實DOM的也是空。
2.ReactTextComponent
通過ReactHostComponent.createInstanceForText()
方法建立,我們直接看mountComponent
即可:
ReactDOMTextComponent
相比ReactDOMEmptyComponent
的處理稍微複雜一些,但是邏輯大致相同。escapeTextContentForBrowser
方法內部對引數進行空格的校驗處理,最終通過簡單的' '+引數
方法將引數轉化為字串並返回。
3.ReactDOMComponent
通過ReactHostComponent.createInternalComponent()
方法建立,同樣我們直接看mountComponent
就好:
因為dom元素同樣沒有生命週期,ReactDOMComponent
會對傳入的div
,span
等標籤通過switch
進行識別和處理,除此之外流程與上述兩類元件基本相同。
4.ReactCompositeComponent
自定義元件是React元件的重點,通過ReactCompositeComponentWrapper()
方法建立,最終呼叫ReactCompositeComponentMixin.mountComponent
方法建立元件的HTML。由於該函式非常長,感興趣的讀者請前往ReactCompositeComponent.js
閱讀原始碼,在此我們直接用圖例給出該函式的邏輯:
基於以上,可以看出生命週期的執行的目的就是為了解析ReactElement
獲得HTML。由此我們更新上一篇文章中的四大元件型別的總結表格:
nextElement |
實際引數 | 結果 |
---|---|---|
null /false |
空 | 建立ReactDOMEmptyComponent 元件 |
object && type === string |
虛擬DOM | 建立ReactDOMComponent 元件 |
object && type !== string |
React元件 | 建立ReactCompositeComponent 元件 |
string |
字串 | 建立ReactDOMTextComponent 元件 |
number |
數字 | 建立ReactDOMTextComponent 元件 |
最後基於第一篇文末給出的思維導圖,我們進行細節完善: (點選可檢視大圖)
回顧:
《React原始碼解析(一):元件的實現與掛載》
《React原始碼解析(三):詳解事務與更新佇列》
《React原始碼解析(四):事件系統》
聯絡郵箱:ssssyoki@foxmail.com