-
ReactDom.render函數(shù)有兩個(gè)功能,1、判斷傳入的容器是否是dom元素,2、調(diào)用legacyRenderSubtreeIntoContainer函數(shù) - 調(diào)用
legacyRenderSubtreeIntoContainer傳入了5個(gè)參數(shù)image.pnglegacyRenderSubtreeIntoContainer函數(shù)接受5個(gè)參數(shù)
image.png
render調(diào)用時(shí)傳入了element container callback三個(gè)變量值,其余兩個(gè)參數(shù)為null false。具體其余兩個(gè)參數(shù)主要是判斷是否為服務(wù)端渲染和調(diào)和其它渲染,這兒只看render渲染時(shí)傳入的參數(shù)。image.png
由于我們傳入的container是一個(gè)dom元素,所以沒(méi)有_reactRootContainer屬性,會(huì)調(diào)用legacyCreateRootFromDOMContainer方法,給該方法傳入了container forceHydrate參數(shù)。forceHydrate主要來(lái)區(qū)別是服務(wù)端渲染(hydrate)還是客戶端渲染(render)。 -
legacyCreateRootFromDOMContainerimage.png
render函數(shù)調(diào)用時(shí)forceHydrate是傳入的false,因此會(huì)調(diào)用shouldHydrateDueToLegacyHeuristic函數(shù),該函數(shù)傳入container,在render函數(shù)時(shí)會(huì)返回false,居然單獨(dú)看此函數(shù),最終shouldHydrate會(huì)為false,然后會(huì)清除container下面所有元素,最終調(diào)用createLegacyRoot函數(shù)

image.png
-
createLegacyRoot返回一個(gè)ReactDOMBlockingRoot對(duì)象實(shí)例,該實(shí)例的原型鏈上掛載比如render unmount方法
image.pngimage.png
經(jīng)過(guò)一段大規(guī)模的處理,最終root和container._reactRootContainer得到一個(gè)ReactDOMBlockingRoot,所以只需要看ReactDOMBlockingRoot函數(shù)中createRootIml就行,createRootIml函數(shù)調(diào)用了createContainer,而最終image.pngcreateContainer調(diào)用并返回了createFiberRoot函數(shù),,image.pngcreateFiberRoot主要調(diào)用了FiberRootNodeimage.png
前面所有處理的一大堆函數(shù)調(diào)用,最終其實(shí)就是調(diào)用了FiberRootNode函數(shù),返回的是一個(gè)FiberRootNode實(shí)例,只需要關(guān)注該函數(shù)的實(shí)現(xiàn)就好。還需要重點(diǎn)關(guān)注image.png
createHostRootFiber函數(shù),后期會(huì)處理到
已上基本所有代碼都是在處理container相關(guān)代碼 - 最后
unbatchedUpdates updateContainer函數(shù)image.png
image.png - 總結(jié):
ReactDom.render函數(shù)主要是處理傳入的root節(jié)點(diǎn),創(chuàng)建一個(gè)ReactRoot,同時(shí)創(chuàng)建一個(gè)FiberRoot,創(chuàng)建FiberRoot的過(guò)程中也會(huì)創(chuàng)建一個(gè)FiberRoot對(duì)象,根據(jù)創(chuàng)建的FiberRoot去更新。











