聊聊React源码系列 - 虚拟DOM
--- JSX 是什么 ---
我们在React项目中直接使用的开发代码就是JSX,例如
我们在浏览器中将main输出看一下返回的是什么
这个输出的函数 React.createElement就是经过一次babel处理的
--- Babel ---
我们直接在Babel官网中看看一段普通的JSX会被编译成什么
而执行此函数会返回什么呢
--- VitrualDom ---
这个对象就是今天我们要说的重点,虚拟Dom
返回的DOM对象抽取一些重要的属性
{$$typeof: Symbol(react.element)key: nullref: nullprops: { childern: xxx }ref: nulltype: xxx}
这个对象就是虚拟dom
简单总结上述流程
明白了这个DOM生成阶段,我们来重点看看 VitrualDom
自己尝试实现这个生成虚拟DOM的函数
先写只有一个子元素的对象
function createElement(type, config, ...childrens) {let { ref = null, key = null, ...propsConfig } = config || {}const obj = {$$typeof: Symbol.for('react.element'),type,ref,key,props: { ...propsConfig },}// 处理childrenobj.props.children = childrens.length > 1 ? childrens : childrens[0]return obj}
基本的功能完成 👍
虚拟DOM对象转为页面中真实的DOM树,是通过React.render函数,也来写一个render函数
function createReallyDom(virtualDom, root) {const { type, props } = virtualDomconst dom = document.createElement(type)// 遍历处理propsconst { children = [], ...restProps } = props || {}// 处理子元素if (Array.isArray(children) && children.length) {createChildrens(children, root)} else {dom.innerText = children}for (const key in restProps) {dom[key] = restProps[key]}// 真实DOM 写入父节点root.appendChild(dom)}function createChildrens(children, root) {if (Array.isArray(children)) {children.forEach((child) => {createReallyDom(child, root)})} else {createReallyDom(children, root)}}function render(virtualDom, root) {createReallyDom(virtualDom, root)}
一个极简版本的render完成 👍
总结:
虚拟DOM是一个React创建的对象,在浏览器中通过render方法可以渲染出真实DOM节点
