初始化一个项目
npx create-react-app my-appcd my-appnpm start
index.js
import React from 'react';import ReactDOM from 'react-dom';let element = (<div id="A1"><div id="B1"><div id="C1"></div><div id="C2"></div></div><div id="B2"></div></div>)console.log(JSON.stringify(element, null, 2))ReactDOM.render(element, document.getElementById('root'));
经过babel转译过后的虚拟dom json对象
let element = {"type": "div","key": null,"ref": null,"props": {"id": "A1","children": [{"type": "div","key": null,"ref": null,"props": {"id": "B1","children": [{"type": "div","key": null,"ref": null,"props": {"id": "C1"},"_owner": null,"_store": {}},{"type": "div","key": null,"ref": null,"props": {"id": "C2"},"_owner": null,"_store": {}}]},"_owner": null,"_store": {}},{"type": "div","key": null,"ref": null,"props": {"id": "B2"},"_owner": null,"_store": {}}]},"_owner": null,"_store": {}}
简单实现 React 15 之前的渲染方法
function render (element, parentDOM) {// 创建dom元素let dom = document.createElement(element?.type);// 处理属性Object.keys(element.props) // 返回props里的所有key值.filter(key=> key!=='children') // 过滤childer 只要id.forEach(key =>{dom[key] = element.props[key]})if(Array.isArray(element?.props?.children)){// 递归调用插入子节点element.props.children.forEach(child=>render(child,dom))}parentDOM.appendChild(dom)// console.log(Object.keys(element.props).filter(key=> key!=='children'))}render(element, document.getElementById('root'));
存在的问题
1、如果节点多且层级比较深,递归无法退出
2、因为JS是单线程,UI渲染和JS执行是互斥的
