【Under-the-hood-ReactJS-Part0】React源碼解讀

接上文—

完全流程圖見:https://bogdan-lyashenko.gith…
繼承我們的React之旅,讓我們從ReactDOM.render的挪用最先。

ReactDOM.render

ReactDOM.render是我們剖析的進口點。我們的運用從這裏最先襯着內容到DOM樹中。為了輕易調試,我們建立了一個<ExampleApplication/>的簡樸組件。全部流程的第一個行動就是把JSX轉換成React elements 。 React elements就是帶一些架構的簡樸對象。 他們就是用來示意組件render要領的返回值,除此之外,沒有其他的。對象中的一些字段,如props,key,ref關於人人應當已很熟悉了。 type屬性示意的是JSX定義的標記對象,在我們的案例中,就是類 ExampleApplication, 固然,它也能夠示意 Button標籤的字符串花樣等等。 同時,在React element的建立時期,React將會兼并defaultProps和props(假如有聲明的話),而且嚴峻propTypes。
更多詳情請檢察源碼 srcisomorphicclassicelementReactElement.js

ReactMount

在流程圖中,你能夠發現有個叫做ReactMount的模塊。它包含了全部組件掛載的邏輯。
實在,ReactDOM中是沒有任何邏輯的,它不過是一個用來挪用ReactMount的接口,所以當挪用ReactDOM.render要領時,技術上來講,你真正挪用的是ReactMount.render要領。那末全部掛載歷程究竟是怎樣的呢?

Mounting is the process of initializing a React component by creating its representative DOM elements and inserting them into a supplied container.(掛載是指初始化一個React組件的歷程,包含天生組件對應的DOM元素並插進去指定的容器中)

以上筆墨來自於React代碼的詮釋,那末這些究竟是一個怎樣的歷程呢?我們先看下以下的一個轉化:
React須要將你組件里的JSX形貌轉化為對應的HTML構造,並插進去到DOM樹中,這個歷程,
React須要處置懲罰一切的屬性,綁定的事宜,內嵌的組件和一切邏輯。掛載,就是指把用高條理言語形貌的組件(JSX)轉化為低條理的html代碼,然後插進去到DOM樹中。

為了讓以上形貌更細緻下,斟酌以下需求:

目的:確保轉動事宜被監聽

在一個根組件的第一次襯着歷程當中,React會初始化轉動監聽事宜,而且把轉動條相干數值緩存起來,如許,當運用代碼能夠在不觸發重排(reflow)的前提下,訪問到轉動條相干數據。由於差別的遊覽器會有差別的完成,一些DOM的數值黑白牢固的,每次當你在代碼中獵取它們時,它們都有能夠會從新盤算。明顯,這一步驟會引起一些機能題目。比方,一些老的遊覽器,是不支持pageX和pageY屬性的。為了處理這個題目,React會做一些優化,而這些優化歷程當中,能夠就會須要許多別的技能。在別的題目中,React為了處理某個細緻的題目,都邑用到許多技能,轉動條就是一個細緻的列子。

實例化React組件

回憶下最最先的流程圖,這裡有一個實例建立的歷程。事實上,目前往建立一個<ExampleApplication>的實例還有點早,這裏我們真正實例化的是類TopLevelWrapper(React內部類)。我們先跳過這個歷程,看下一個流程。

在JSX的轉化歷程當中,這裡有三個階段。JSX轉化成React elements后,React elements會被轉化為以下內部React組件範例中的一:ReactCompositeComponent(開闢自定義的組件),ReactDOMComponent(HTML DOM節點),ReactDOMTextComponent(文本節點)。我們先疏忽ReactDOMTextComponent,重點放在前兩個。

什麼是內部組件呢?你能夠已聽過假造DOM。假造DOM是一種DOM的示意體式格局,在React的diff差別盤算以及別的歷程當中,運用假造DOM使得能夠不直接DOM樹,而這恰是React機能不錯的緣由之一。實在,在React的源碼中,並沒有什麼文件或許類被稱作假造DOM,由於假造DOM只是一種觀點,一種用來形貌怎樣處置懲罰實在DOM的手腕。有些人能夠會說假造DOM示意的就是React elements,然則我不這麼以為。在我看來,假造DOM指的是這三個類:ReactCompositeComponent,ReactDOMComponent,ReactDOMTextComponent。稍後我會細緻詮釋緣由。

讓我們繼承組件的實例化。我們會建立一個ReactCompositeComponent的實例,然則,
這個實例並不是由於我們將<ExampleApplication/>放入ReactDOM.render中然後才天生的。React老是從TopLevelWrapper里最先襯着一個組件樹。它險些是一個純包裝組件,它的render要領(組件的render要領)將會返回<ExampleApplication/>。代碼以下:

//src\renderers\dom\client\ReactMount.js#277
TopLevelWrapper.prototype.render = function () {
  return this.props.child;
};

依據以上代碼,很明顯只要一個TopLevelWrapper的實例被建立了,除此之外就沒有別的的了。在繼承下一步之前,我們看下以下內容:

DOM內嵌考證

險些每次內嵌組件襯着時,它們都邑被一個特地用來做HTML考證的模塊–validateDOMNesting–來考證構造是不是正當。所謂的DOM內嵌考證是指校驗子模塊和父模塊的標籤條理。比方,假如父組件的標籤是<select>,子組件的標籤只能是以下中的一個:optino,optgroup,#text。 這些劃定規矩都是在
https://html.spec.whatwg.org/… 被定義的。你極能夠已看到過這個模塊的事情效果,它會發生以下的毛病提示:<div>不能為<p>的子女湧現(<div> cannot appear as a descendant of <p> .)

好了,讓我們追念下之前的內容,然後再回憶下掛載相干的流程圖。 Part0的部份就是這些。

(未完待續)

    原文作者:剡山
    原文地址: https://segmentfault.com/a/1190000015405537
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞