国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

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

Turbo / 3142人閱讀

摘要:接上文完整流程圖見繼續我們的之旅,讓我們從的調用開始。他們就是用來表示組件方法的返回值,除此之外,沒有其他的。同時,在的創建期間,將會合并和如果有聲明的話,并且嚴重。顯然,這一步驟會引起一些性能問題。

接上文---

完整流程圖見:https://bogdan-lyashenko.gith...
繼續我們的React之旅,讓我們從ReactDOM.render的調用開始。

ReactDOM.render

ReactDOM.render是我們分析的入口點。我們的應用從這里開始渲染內容到DOM樹中。為了方便調試,我們創建了一個的簡單組件。整個流程的第一個動作就是把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組件

回顧下最開始的流程圖,這里有一個實例創建的過程。事實上,目前去創建一個的實例還有點早,這里我們真正實例化的是類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的實例,但是,
這個實例并不是因為我們將放入ReactDOM.render中然后才生成的。React總是從TopLevelWrapper里開始渲染一個組件樹。它幾乎是一個純包裝組件,它的render方法(組件的render方法)將會返回。代碼如下:

//src
enderersdomclientReactMount.js#277
TopLevelWrapper.prototype.render = function () {
  return this.props.child;
};

根據以上代碼,很顯然只有一個TopLevelWrapper的實例被創建了,除此之外就沒有其它的了。在繼續下一步之前,我們看下以下內容:

DOM內嵌驗證
幾乎每次內嵌組件渲染時,它們都會被一個專門用來做HTML驗證的模塊--validateDOMNesting--來驗證結構是否合法。所謂的DOM內嵌驗證是指校驗子模塊和父模塊的標簽層次。比如,如果父組件的標簽是