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

接上文,git

React流程圖:
https://bogdan-lyashenko.gith...github

事務

到如今這一步,組件實例已經經過某種方式加入到React的生態系統中了,同時,React也會對組件進行一些處理,好比ReactUpdates這個專門的模塊。正如你們所知,React是批量處理更新的,也就是說,React會收集全部操做而後一次性操做掉。採用這種方式,一些先置條件和後置條件只須要運行一次,避免了每次更新時都要運行的弊端。緩存

那麼React是如何處理這些先置和後置條件的呢?答案就是事務(transaction)。 對於一些人來講這個多是一個新的詞彙,尤爲是從UI角度的解釋。爲了更好的解釋這個,咱們先從一個簡單的案例開始。app

假設有個通訊管道,每次通訊前,你都須要先創建鏈接,而後發送數據,最後關閉鏈接。若是你有不少信息須要發送,你須要重複屢次這些步驟,這些步驟都須要不少的開銷。可是,所謂的事務就是你只創建一次鏈接,而後把全部消息一次性都發送過去,最後關閉鏈接便可。svg

咱們在把這個過程更泛化下,能夠把‘發送信息’認爲一次你想作的操做,‘創建/關閉’鏈接對應於執行一次操做的‘前置/後置‘條件。而後,你能夠單獨定義創建/關閉標誌,而後在任何方法中使用他們(咱們能夠把這些創建/關閉標誌稱爲包裝器(wrappers),由於每一個包裝器都會包裝某個動做方法)。函數

回到React,事務是React中普遍採用的一種模式。先不論包裝行爲,事務容許應用重置事務流,阻塞一個已經在執行過程當中的同步方法等等。React中有不少不一樣的事務類,每一個類都描述一種具體的行爲,可是每一個類都是繼承自Transaction模塊。每種事務對應的鍵值和特定的事務包裝類是對應的。包裝器就是一個擁有initialize方法和close方法的對象。線程

總之,大概的過程就是:code

  • 調用每一個包裝器的initialize方法,而後緩存其返回值
  • 調用事務方法自己
  • 調用包裝器的close方法

來看些React中其它使用事務的場景:component

  • 保留輸入框的選擇範圍,以便在同步Dom結構以前/以後,其實事件發送錯誤,依然可以恢復選擇
  • 在重排DOM防止失焦/聚焦時中止事件,確保重排以後,事件系統從新激活
  • 在遊覽器的工做線程中發生同步Dom結構後,將收集到的DOM變化隊列刷新到UI渲染主線程上
  • 渲染新內容後,調用收集的componentDidUpdaate的回調函數。

瞭解以上內容後,回到咱們一開始的實例代碼。
從流程圖中能看出,React調用了類ReactDefaultBatchingStrategyTransaction 。就像咱們在上面的內容裏所說的,一個事務類的關鍵是它的包裝器。 因此,咱們詳細看下包裝器,而後試着找出事務的精肯定義。 兩個包裝器 FLUSH_BATCHED_UPDATES,RESET_BATCHED_UPDATES. 先看下源碼:對象

//\src\renderers\shared\stack\reconciler\ReactDefaultBatchingStrategy.js#19
var RESET_BATCHED_UPDATES = {
      initialize: emptyFunction,
      close: function() {
        ReactDefaultBatchingStrategy.isBatchingUpdates = false;
      },
};

var FLUSH_BATCHED_UPDATES = {
     initialize: emptyFunction,
     close: ReactUpdates.flushBatchedUpdates.bind(ReactUpdates),
}

var TRANSACTION_WRAPPERS = [FLUSH_BATCHED_UPDATES, RESET_BATCHED_UPDATES];

正如你所見,這個事務類沒有先置條件。initialize方法是個空方法,但其中有個close方法--ReactUpdates.flushBatchedUpdates卻值得注意。它的做用是,在之後的從新渲染中開始髒組件的驗證過程。咱們調用掛載方法,並把它包裝進這個事務中,這是爲了在掛載動做後,React會檢查已掛載組件影響到了哪些內容,並更新這些內容。再看下流程圖裏被包裝進事務的方法,事實上,這個方法會調用另一個事務。。。(未完待續)

相關文章
相關標籤/搜索