我们先来看一个简单的 demo:
import * as React from 'react';import * as ReactDOM from 'react-dom';class App extends React.Component {render() {return (<div className="container"><div className="section"><h1>This is the title.</h1><p>This is the first paragraph.</p><p>This is the second paragraph.</p></div></div>);}}ReactDOM.render(<App />, document.getElementById('root'));首次渲染的调用栈如下图

文章插图
以 performSyncWorkOnRoot 和 commitRoot 两个方法为界限 , 可以把 ReactDOM.render 分为三个阶段:
- Init
- Render
- Commit
export function render(element: React$Element<any>,container: Container,callback: ?Function,) {// 省略对 container 的校验逻辑return legacyRenderSubtreeIntoContainer(null,element,container,false,callback,);}这里需要注意一点 , 此时的 element 已经不是 render 中传入的了 , 而是经过 React.createElement 转换后的一个 ReactElement 对象 。legacyRenderSubtreeIntoContainer在这里我们可以看到方法取名的重要性 , 一个好的方法名可以让你一眼就看出这个方法的作用 。legacyRenderSubtreeIntoContainer , 顾名思义 , 这是一个遗留的方法 , 作用是渲染子树并将其挂载到 container 上 。再来看一下入参 , children 和 container 分别是之前传入 render 方法的 App 元素和 id 为 root 的 DOM 元素 , 所以可以看出这个方法会根据 App 元素生成对应的 DOM 树 , 并将其挂在到 root 元素上 。
function legacyRenderSubtreeIntoContainer(parentComponent: ?React$Component<any, any>,children: ReactNodeList,container: Container,forceHydrate: boolean,callback: ?Function,) {let root: RootType = (container._reactRootContainer: any);let fiberRoot;if (!root) {root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container,forceHydrate,);fiberRoot = root._internalRoot; // 省略对 callback 的处理逻辑unbatchedUpdates(() => {updateContainer(children, fiberRoot, parentComponent, callback);});} else {// 省略 else 逻辑}return getPublicRootInstance(fiberRoot);}下面来细看一下这个方法:- 首次挂载时 , 会通过 legacyCreateRootFromDOMContainer 方法创建 container.
- 春季老年人吃什么养肝?土豆、米饭换着吃
- 三八妇女节节日祝福分享 三八妇女节节日语录
- 老人谨慎!选好你的“第三只脚”
- 校方进行了深刻的反思 青岛一大学生坠亡校方整改校规
- 脸皮厚的人长寿!有这特征的老人最长寿
- 长寿秘诀:记住这10大妙招 100%增寿
- 春季老年人心血管病高发 3条保命要诀
- 眼睛花不花要看四十八 老年人怎样延缓老花眼
- 香槟然能防治老年痴呆症? 一天三杯它人到90不痴呆
- 老人手抖的原因 为什么老人手会抖
