ReactDom.render分析

12次阅读

共计 1939 个字符,预计需要花费 5 分钟才能阅读完成。

1. 步骤
1. 创建 ReactRoot
2. 创建 FiberRoot 和 FiberRoot
3. 创建更新
2. render 方法:
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 方法执行后的结果,再来看看这个方法的参数
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 方法更新:
unbatchedUpdates(() => {
if (parentComponent != null) {
root.legacy_renderSubtreeIntoContainer(
parentComponent,
children,
callback,
);
} else {
root.render(children, callback);
}
});
执行 updateContainer(children, root, null, work._onCommit); 方法,这个方法最终调用 enqueueUpdate 和 scheduleWork, 并返回 expireTime,这些进行调度算法和进行优先级判断

正文完
 0