React render流程梳理

前端小板凳發表於2019-05-11

前言

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));
複製程式碼

當通過create-react-app初始化一個專案的時候,上面這段程式碼就在瀏覽器中繪製出了內容.ReactDOM.render(ReactElement, Container, callback)是怎麼將React元件繪製到瀏覽器中的呢?本文是React原始碼閱讀系列的起始篇,在這篇文章中主要圍繞以下兩個方面進行介紹:

  1. render()方法呼叫中相關函式的呼叫
  2. render()方法呼叫中產生的資料結構的梳理

閱讀原始碼是一個知其然知其所以然的過程.通過原始碼閱讀的過程中我們能學習到一些設計,程式碼優化,解決方案等,通過這些來反哺實際工作的遇到的問題.這個也是這個系列想要獲得並且與大家分享的內容.

如何閱讀React原始碼

  1. React倉庫是一個包含多個package的倉庫.在閱讀原始碼之前需要對獨立的倉庫有個簡單的認識.比如react通過react-reconciler和react-dom來完成web頁面的構建.
    reactPackage
  2. debugger
    通過debugger來一步一步跟蹤函式的呼叫.

ReactDOM.render()呼叫過程中的函式呼叫

以下所有程式碼基於React 16.8.6

  • reactRenderFunc

走入ReactDOM.render()原始碼

首先定位到packages/react-dom/src/client/ReactDOM.js
domRender
可以看到ReactDOM.render()方法將當前的ReactElement和Container資訊傳遞給了legacyRenderSubtreeIntoContainer.
containerRender
由於是首次mount,這個時候還沒有root節點並且是應用的根節點這裡直接進行root節點的建立.最後呼叫root的render方法就開始進行頁面的繪製.在legacyCreateRootFromDOMContainer方法中會對當前容器的內容進行清理.這裡呼叫建立了ReactRoot節點.
createReactRoot
reactRoot
createContainer根據當前的container資訊來建立根容器.
定位到packages/react-reconciler/src/ReactFiberReconciler.js
createContainer
定位到packages/react-reconciler/src/ReactFiberRoot.js(Fiber !!!!!!)
在createFiberRoot方法中,建立了根據當前的容器資訊建立了FiberRootb並且建立了一個HostRootFiber進行相互引用.
createFiberRoot

ReactDOM.render()呼叫過程中的資料結構

reactStruct
通過啟動最開始create-react-app建立的專案,可以看到以下的輸出.
showRenderStruct

後記

這篇文章只梳理了React在實際呼叫渲染函式之前的函式呼叫和資料結構.在這個過程中終於盼來了千呼萬喚的fiber.之後的文章會繼續深入react的渲染流程和fiber的實現來對react進行學習.

                                            React render流程梳理

                                                歡迎大家關注我的公眾號,一起進步


相關文章