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的基本搭建。