render( element: React$Element<any>, container: DOMContainer, callback: ?Function, ) { invariant( isValidContainer(container), 'Target container is not a DOM element.', ); return legacyRenderSubtreeIntoContainer( null, element, container, false, callback, ); },
render方法能夠傳入三個參數包括ReactElement、DOM的包裹節點,和渲染結束後執行的回調方法。
而後驗證invariant
驗證container是不是有效的Dom節點。
最後返回legacyRenderSubtreeIntoContainer
方法執行後的結果,再來看看這個方法的參數react
function legacyRenderSubtreeIntoContainer( parentComponent: ?React$Component<any, any>, children: ReactNodeList, container: DOMContainer, forceHydrate: boolean, callback: ?Function, )
這裏傳入五個參數,第一個是parentComponent不存在傳入null,第二個是傳入container的子元素,第三個是建立ReactRoot的包裹元素,第四個是協調更新的選項,第五個是渲染後的回調方法。
let root: Root = (container._reactRootContainer: any); if (!root) { // Initial mount root = container._reactRootContainer = legacyCreateRootFromDOMContainer( container, forceHydrate, );
先檢驗ReactRoot是否存在不存在則執行傳入container,
forceHydrate後的legacyCreateRootFromDOMContainer
函數建立一個ReactRoot。forceHydrate在render方法中傳入的false,在Hydrate方法中傳入的true,主要是爲了區分服務端渲染和客戶端渲染,true時未複用原來的節點適合服務端渲染,
若是是false則執行container.removeChild(rootSibling)
刪除全部的子節點。
而後返回經過new ReactRoot(container, isConcurrent, shouldHydrate)
:
function ReactRoot( container: DOMContainer, isConcurrent: boolean, hydrate: boolean, ) { const root = createContainer(container, isConcurrent, hydrate); this._internalRoot = root; }
在這個方法中調用createContainer
建立root,這個方法從react-reconciler/inline.dom
文件中引入:算法
export function createContainer( containerInfo: Container, isConcurrent: boolean, hydrate: boolean, ): OpaqueRoot { return createFiberRoot(containerInfo, isConcurrent, hydrate); }
在這個方法中又調用了createFiberRoot
方法建立FiberRoot
在建立玩root後執行unbatchedUpdates
更新,傳入root。render方法更新:dom
unbatchedUpdates(() => { if (parentComponent != null) { root.legacy_renderSubtreeIntoContainer( parentComponent, children, callback, ); } else { root.render(children, callback); } });
執行updateContainer(children, root, null, work._onCommit);
方法,這個方法最終調用enqueueUpdate
和scheduleWork
,並返回expireTime,這些進行調度算法和進行優先級判斷函數