首页 > IT职业 > IT生活 > ReactDom.render学习笔记
最近在学习React 源码深度解析 高级前端工程师必备技能》https://s.imooc.com/SUq8J2i
源码部分其中一节讲了ReactDom.render()创建更新。
整理如下 MarkDown使用不是很熟练将就看
ReactDom.render()ReactDom.render()接受3个参数,element、container、callback
返回下方代码的执行结果。
legacyRenderSubtreeIntoContainer( null, element,container, false,callback)
legacyRenderSubtreeIntoContainer
legacyRenderSubtreeIntoContainer接收5个参数:
(parentComponent 、 children、container、forceHydrate、callback)
在这个方法中 定义
root = container.reactRootContainer =
legacyCreateRootFromDOMContainer(container, forceHydrate,)
通过 new React()*创建ReactRoot对象的方法下面有说明 *
后执行
root.render (children, callback)
也就是
container.reactRootContainer.render(children, callback);
最后返回
return DOMRenderer.getPublicRootInstance(root._internalRoot) 返回实例
由上文legacyCreateRootFromDOMContainer(container, forceHydrate,)方法创建添加的属性
_internalRoot。
legacyCreateRootFromDOMContainer创建返回ReactRoot
function legacyCreateRootFromDOMContainer(
container: DOMContainer,
forceHydrate: boolean, // 是否复用已有子节点
): Root {
/* 不重要 忽略
const shouldHydrate =
forceHydrate || shouldHydrateDueToLegacyHeuristic(container)
// First clear any existing content.
if (!shouldHydrate) {
let warned = false
let rootSibling
while ((rootSibling = container.lastChild)) {
container.removeChild(rootSibling)
}
}
*/
// Legacy roots are not async by default.
const isConcurrent = false
return new ReactRoot(container, isConcurrent, shouldHydrate) // 创建ReactRoot
}
function ReactRoot(
container: Container,
isConcurrent: boolean,
hydrate: boolean,
) {
// 这个root 不是上面的 root
const root = DOMRenderer.createContainer(container, isConcurrent, hydrate)
this._internalRoot = root
}
也就是说ReactRoot._internalRoot// 内部本质root
其实等于DOMRenderer.createContainer(container, isConcurrent, hydrate)
结合
上面的2. legacyRenderSubtreeIntoContainer
root
= container.reactRootContainer
=legacyCreateRootFromDOMContainer(container, forceHydrate)
= => new ReactRoot
省略中间步骤 root <=> new ReactRoot()
结合function ReactRoot
root._internalRoot 也其实就是 DOMRenderer.createContainer(container, isConcurrent, hydrate)返回,一个 FiberRoot。
也就是说 上面2. legacyRenderSubtreeIntoContainer 实际上创建了一个 ReactRoot 并返回其公共根实例(getPublicRootInstance)
return DOMRenderer.getPublicRootInstance(root._internalRoot)返回实例
root._internalRoot=DOMRenderer.createContainer(container, isConcurrent, hydrate))root._internalRoot) // 接收一个FiberRoot返回其公共根实例
root为一个ReactRoot;root._inernalRoot为一个FiberRoot,render方法也是第二部分的开始;ReactRoot.render()主要执行 DOMRenderer.updateContainer(children, root, null, work._onCommit)
其中root实际上为第一部分的ReactRoot._ineralRoot也就是FiberRoot,
而work._onCommit实际上为最开始传入的callback
updateContainer()
function updateContainer(
element: ReactNodeList,
container: OpaqueRoot,
parentComponent: ?React$Component<any, any>,
callback: ?Function,
): ExpirationTime {
const current = container.current
const currentTime = requestCurrentTime()
// 计算更新超时时间
const expirationTime = computeExpirationForFiber(currentTime, current)
// 用超时时间来更新。
return updateContainerAtExpirationTime(
element,
container,
parentComponent,
expirationTime,
callback,
)
}
updateContainerAtExpirationTime调用了scheduleRootUpdate
function updateContainerAtExpirationTime(
element: ReactNodeList,
container: OpaqueRoot,
parentComponent: ?React$Component<any, any>,
expirationTime: ExpirationTime,
callback: ?Function,
) {
// TODO: If this is a nested container, this won't be the root.
const current = container.current
const context = getContextForSubtree(parentComponent)
if (container.context === null) {
container.context = context
} else {
container.pendingContext = context
}
return scheduleRootUpdate(current, element, expirationTime, callback)
}
scheduleRootUpdate
3.1生成一个update
3.2添加到更新队列enqueueUpdate(current, update)
3.3开始任务调度。 // 后续内容
3.4返回expirationTime
感谢能坚持看到这里 给点建议吧。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/3127/viewspace-2820256/ ,如需转载,请注明出处,否则将追究法律责任。