本节目标实现ReactDOM.render,只关心向 DOM 添加内容,之后处理更新和删除内容;
本节代码实现目录为:react/react-dom.js文件;
有了虚拟 DOM 数据结构,接下来要把它转换成真实的DOM结构渲染到页面上,基本分为四步:
- 创建不同类型节点
- 添加属性 props
- 遍历 children,递归调用 render
- 将生成的节点 append 到 root 根节点上
具体实现步骤:
1、新建react-dom.js文件
2、创建 DOM 节点,然后将新节点添加到容器
// react/react-dom.js
/**
* 将虚拟 DOM 转换为真实 DOM 并添加到容器中
* @param {element} 虚拟 DOM
* @param {container} 真实 DOM
*/
function render(element, container) {
const dom = document.createElement(element.type)
container.appendChild(dom)
}
3、将 element.props.children 都添加至 dom 节点中
element.props.children.forEach(child =>
render(child, dom)
)
4、处理文本节点
const dom =
element.type == "TEXT_ELEMENT"
? document.createTextNode("")
: document.createElement(element.type)
5、为节点绑定属性
// 为节点绑定属性
const isProperty = key => key !== "children"
Object.keys(element.props)
.filter(isProperty)
.forEach(name => {
dom[name] = element.props[name]
})
6、测试
以上我们实现了一个jsx转换为dom的库,测试一下:
6.1 将render方法引入到react/index.js文件中
6.2 添加React.render方法
在src/index.js文件添加React.render方法:
// src/index
import React from '../react';
const element = (
<div id="foo">
<a>bar</a>
<b />
</div>
)
React.render(element, document.getElementById('root'))
6.3 修改webpack配置
在src目录下添加index.html文件,并添加一个dom属性为id的节点:
修改webpack配置,添加html模板:
6.4 运行
运行命令 npm run start 启动,可以看到已经成功显示出结果:
7、总结
使用流程图简单总结一下2、3小节: