先断点调试找下调用链条
- render
- legacyRenderSubtreeIntoContainer
- updateContainer
- scheduleWork(scheduleUpdateOnFiber)
- performSyncWorkOnRoot
- finishSyncRender
- commitRoot
- runWithPriority
- commitRootImpl
- invokeGuardedCallback
- commitMutationEffects
- commitPlacement
- insertOrAppendPlacementNodeIntoContainer
- appendChildToContainer
- appendChildToContainer
- parentNode.appendChild(child)
我们按顺序来看下每个方法做了什么事情
function legacyRenderSubtreeIntoContainer(
parentComponent: ?React$Component<any, any>,
children: ReactNodeList,
container: Container,
forceHydrate: boolean,
callback: ?Function,
) {
let root: RootType = (container._reactRootContainer: any);
let fiberRoot;
// 这里根据root判断是否初次挂载(initial mount)
if (!root) {
// 根据container创建一个firberRoot,并挂到container上,名称为_reactRootContainer
root = container._reactRootContainer = legacyCreateRootFromDOMContainer(
container,
forceHydrate,
);
fiberRoot = root._internalRoot;
unbatchedUpdates(() => {
// 执行到这里
updateContainer(children, fiberRoot, parentComponent, callback);
});
}
return getPublicRootInstance(fiberRoot);
}
从代码上看,legacyRenderSubtreeIntoContainer方法主要是创建了一个"firberRoot",然后执行updateContainer方法。
legacyRenderSubtreeIntoContainer这个方法最终调用的是一个叫createFiberRoot的方法,我们线看下这个方法
export function createFiberRoot(
containerInfo: any,
tag: RootTag,
hydrate: boolean,
hydrationCallbacks: null | SuspenseHydrationCallbacks,
): FiberRoot {
const root: FiberRoot = (new FiberRootNode(containerInfo, tag, hydrate): any);
const uninitializedFiber = createHostRootFiber(tag);
root.current = uninitializedFiber;
uninitializedFiber.stateNode = root;
initializeUpdateQueue(uninitializedFiber);
return root;
}
export function updateContainer(
element: ReactNodeList,
container: OpaqueRoot,
parentComponent: ?React$Component<any, any>,
callback: ?Function,
): ExpirationTime {
const current = container.current;
const currentTime = requestCurrentTimeForUpdate();
const suspenseConfig = requestCurrentSuspenseConfig();
const expirationTime = computeExpirationForFiber(
currentTime,
current,
suspenseConfig,
);
// 取createFiberRoot方法时添加的current,并执行scheduleWork方法
scheduleWork(current, expirationTime);
return expirationTime;
}
先断点调试找下调用链条
我们按顺序来看下每个方法做了什么事情
从代码上看,legacyRenderSubtreeIntoContainer方法主要是创建了一个"firberRoot",然后执行updateContainer方法。
legacyRenderSubtreeIntoContainer这个方法最终调用的是一个叫createFiberRoot的方法,我们线看下这个方法