-
Notifications
You must be signed in to change notification settings - Fork 0
Description
研究的 React 版本为 15.x。
ReactDom.render
通常 ReactDom.render 是整个 React 应用的入口,以 ReactDom.render(<ExampleApplication />, DOMNode) 为例,其内部执行过程如图:
1. JSX => ReactElement
ReactDom.render 首先要做的就是把 JSX 的语法糖通过 React.createElement 函数转换为 ReactElement。
2. 调用 ReactMount 模块
组件实际挂载逻辑是在 ReactMount 模块中处理的,调用 ReactDom.render 实际是在调用 ReactMount.render。
组件挂载即通过构造实际 DOM 节点并把它插入到父节点来初始化组件的过程。
3. 模拟滚动
在根组件第一次渲染时,React 会初始化 scroll 监听器并缓存 scroll 相关值,这样做的好处时在获取这些数据的时候可以避免 reflow。
4. 实例化组件
该阶段会把 ReactElement 转换为 React 内部特定的组件类型:
Component Element=>ReactCompositeComponentDom Element=>ReactDOMComponenttest string=>ReactDOMTextComponent
通常意义上会把 ReactElement 认为是 Virtual DOM,但是实际上可能 ReactXComponent 才是真正的 Virtual DOM。
文章开始的图中,ExampleApplication 组件作为参数传入 ReactDom.render,然后在实例化组件的过程中会调用 ReactCompositeComponentWrapper 构造函数来实例化 ExampleApplication,但是事实是,无论传入什么类型的组件,ReactMount.render 都会先调用 ReactCompositeComponentWrapper 构造函数来构造组件树,理由是整个组件树的最顶层不是 ReactDom.render 传入的组件,而是内置的一个组件 TopLevelWrapper:
//src\renderers\dom\client\ReactMount.js#277
TopLevelWrapper.prototype.render = function () {
return this.props.child;
};通过 TopLevelWrapper 的渲染函数将 ExampleApplication 返回。
在继续渲染 ExampleApplication 之前,React 需要校验嵌套的 DOM(validateDOMNesting),即校验 DOM 节点的层级关系,有些父节点标签的子节点标签只能是特定的标签集合,比如 select 标签的子标签只能是 option,optGroup 或 #text。

