07.实现 render、mount 和 createDOM进行初次渲染
具体代码变化过程请观看视频,这里把关键代码展示出来:
js
import { REACT_ELEMENT } from './utils'
function render(VNode, containerDOM){
mount(VNode, containerDOM)
// 有同学会觉得奇怪,为什么不把mount函数的逻辑放到这里,还少一次函数调用,
// 事实上,render函数不仅仅只做挂载这样一件事情,只不过我们这里暂未涉及
}
function mount(VNode, containerDOM){
let newDOM = createDOM(VNode)
newDOM && containerDOM.appendChild(newDOM);
}
function createDOM(VNode){
// 根据虚拟DOM创建真实DOM要做三件事情: 1.创建元素 2.处理子元素 3.处理元素属性
const {type, props} = VNode
let dom;
if (type && VNode.$$typeof === REACT_ELEMENT) {
dom = document.createElement(type);
}
// 处理子元素
if(props){
// 这里我们要纠正上一小节关于createElement的一行代码,children数组
if (typeof props.children === 'object' && props.children.type) {
mount(props.children, dom)
} else if (Array.isArray(props.children)) {
mountArray(props.children, dom);
} else if (typeof props.children === 'string'){
dom.appendChild(document.createTextNode(props.children));
}
}
// 处理属性
return dom
}
f
function mountArray(children, parent){
if(!Array.isArray(children)) return
for (let i = 0; i < children.length; i++) {
if (typeof children[i] === 'string'){
parent.appendChild(document.createTextNode(children[i]))
}else{
mount(children[i], parent)
}
}
}
const ReactDOM = {
render
}
export default ReactDOM我们来观察项目执行情况,会发现页面上展示了视频中我们所期待的字符串。不过虽然这里实现了render、mount、createDOM几个函数,但这里只是处理了最简单的场景,随着课程的深入,这些函数的内容还会不断完善。