1. dom节点渲染
const dom = document.createElement('div') dom.id = 'app' const textNode = document.createTextNode('') textNode.nodeValue = 'Hello world' dom.append(textNode) const container = document.querySelector("#app") container.append(dom)
由上图可知,一个dom节点需要type,props,children。掌握这一层,下边一些API的实现就是基于它去演化的。
我们都了解react的children是存入props中的,为了方便访问和传递,组件复用,以及通过将children存入props中,可以支持树状结构的组件嵌套。并且将children转化为数组,可以处理多个子元素的情况。通过将子元素转化为数组,我们可以轻松地对子元素进行遍历、筛选、映射等操作,从而实现更灵活的组件组合方式。
// 创建dom节点 function createElement(type,props,...children) { return { type, props:{ ...props, children } } }
2. react搭建的Api的引用
import { ReactDom } from "./core/ReactDom.js" import App from "./App.js" ReactDom.createRoot(document.querySelector("#app")).render(App)
// 创建dom节点 function createElement(type,props,...children) { return { type, props:{ ...props, children:children.map(child => { return typeof child === 'string' ? createTextNode(child) : child }) } } } function render(el,container) { console.log(el); const { type,props } = el const dom = type === 'TEXT_ELEMENT' ? document.createTextNode("") : document.createElement(type) if(props) { Object.keys(props).forEach(key => { if(key !== 'children') { dom[key] = props[key] } }) props.children.forEach(child => { render(child,dom) }) } container.append(dom) } function createTextNode(text) { return { type:'TEXT_ELEMENT', props:{ nodeValue: text, children:[] } } } const React = { createElement, render } export default React
import React from "./React.js" export const ReactDom = { createRoot(container) { return { render(App){ React.render(App,container) } } } }
由于react的原理其实就是一个vdom,也就是一个js对象。将我们定义的type,props,children通过createElement转化为虚拟节点,然后调用render函数,通过type定义dom,然后循环props的key值,key值为children时采用循环递归处理,最后将其挂载到容器上。
3. 了解了基本的dom渲染以及api的引用。我们就可以通过命令进行框架的一个搭建,并且使用JSX文件
采用npm create vite创建项目
将原先的App.js,main.js复制过去,将其改为jsx后缀。发现并没有造成什么影响。并且我们在App.jsx里可以去除React.createElement的调用,直接写成标签,发现如果不调用craeteElement,页面依然可以正常渲染。其实是编译时会自动将其转化并且调用我们的React.createElement函数。
import React from "./core/React.js" // const App = React.createElement('div',null,'123') // 编译会自己调用React.createElement const App = <div>hello world</div> export default App
以上就是我们对mini-react的基本搭建。