react解析: render的FiberRoot(三)
下面将会说到 ReactDOM.render
在ReactDOM中的调用流程,实际就是分析下面代码:
ReactDOM.render(<APP />, document.getElementById('app'))
实际代码:
ReactDOM.render(React.createElement(APP, null), document.getElementById('app'));
render 函数
ReactDOM.render实际调用的就是下面的代码
render(
element: React$Element<any>,
container: DOMContainer,
callback: ?Function,
) {
// 注意下 forceHydrate 参数,为 true 时是服务端渲染
// 客户端调用 render 函数的话这个值永远为 false
return legacyRenderSubtreeIntoContainer(
null,
element,
container,
false,
callback,
);
}
legacyRenderSubtreeIntoContainer 函数
function legacyRenderSubtreeIntoContainer(
parentComponent: ?React$Component<any, any>,
children: ReactNodeList,
container: DOMContainer,
forceHydrate: boolean,
callback: ?Function,
) {
// 初始化时,container 肯定没有 _reactRootContainer属性
let root: Root = (container._reactRootContainer: any);
if (!root) {
root = container._reactRootContainer = legacyCreateRootFromDOMContainer(
container, // DOM容器节点
forceHydrate, // 为false
);
// 暂时只说root不存在时,reactRoot的创建
}
}
container
表示DOM元素节点容器, 在上面的代码中会创建一个ReactRoot,然后将它挂载在container容器上, container._reactRootContainer
就是挂载的ReactRoot属性。
// 查看_reactRootContainer
document.getElementById('app')._reactRootContainer
创建FiberRoot核心函数
function legacyCreateRootFromDOMContainer(
container: DOMContainer,
forceHydrate: boolean,
): Root {
const isConcurrent = false;
// 调用ReactRoot函数 创建ReactRoot, shouldHydrate是SSR相关,不用管
return new ReactRoot(container, isConcurrent, shouldHydrate);
}
function ReactRoot(
container: DOMContainer,
isConcurrent: boolean,
hydrate: boolean,
) {
// 这个 root 指的是 FiberRoot
const root = createContainer(container, isConcurrent, hydrate);
this._internalRoot = root;
}
调用createContainer 创建FiberRoot,下面我们将会说到FiberRoot 对象
FiberRoot
export function createContainer(
containerInfo: Container,
isConcurrent: boolean,
hydrate: boolean,
): OpaqueRoot {
return createFiberRoot(containerInfo, isConcurrent, hydrate);
}
function createFiberRoot(
containerInfo: any,
isConcurrent: boolean,
hydrate: boolean,
): FiberRoot {
const root: FiberRoot = (new FiberRootNode(containerInfo, hydrate): any);
const uninitializedFiber = createHostRootFiber(isConcurrent);
root.current = uninitializedFiber;
uninitializedFiber.stateNode = root;
return root;
}
createFiberRoot函数中,首先创建了一个root: FiberRoot
,然后又创建了一个uninitializedFiber: RootFiber
,它们两者还是相互引用。
// 查看 FiberRoot 对象
document.getElementById('app')._reactRootContainer._internalRoot
我们下面顺便说一下FiberRoot 和 RootFiber的关系,同时拿出几个必须要要了解的属性解释一下。
ReactDom.render(
()=> (
<div>
<div></div>
<div></div>
</div>
),
document.querySelector('#root')
)
img
更多内容:
参考:
ps: 顺便推一下自己的个人公众号:Yopai,有兴趣的可以关注,每周不定期更新,分享可以增加世界的快乐
image