【组件本质学习】
import React, {Component, useState, useEffect,} from 'react';
class MyComponent {
render() {
return {
tag: 'div'
}
}
}
// 函数式组件:
//
// 是一个纯函数
// 没有自身状态,只接收外部数据
// 产出 VNode 的方式:单纯的函数调用
// 有状态组件:
//
// 是一个类,可实例化
// 可以有自身状态
// 产出 VNode 的方式:需要实例化,然后调用其 render 函数
export default () => {
// // init方法用来创建patch函数
// const patch = init([])
// // 我所创建的组件, 组件的作用就是返回一个虚拟dom
// /****
// *
// * @param props
// * @constructor
// * Virtual DOM带来了分层设计,它对渲染过程的抽象,使得框架可以渲染到web(浏览器)
// * 以外的平台,以及能够实现SSR(Server Side Rendering)
// */
// const MyComponent = (props: any) => {
// return h('h1', props.title)
// }
// // 组件返回的是虚拟DOM
// const prevVnode = MyComponent({title: 'aaa'});
// // 调用patch函数渲染为真实DOM
// patch(document.body, prevVnode);
//
// // 数据变化,返回新的VNode
// const nextVnode = MyComponent({title: 'sunwukong1'});
// // 通过对比新旧Vnode, 高效的渲染真实DOM
// patch(prevVnode, nextVnode)
// console.log('aaaaa', patch(document.body, prevVnode));
//---------------------------------------------
//Vnode 用如下对象表示一个div标签
const elementVnode = {
tag: 'div'
};
// 表示一个虚拟组件Vnode
const componentVnode = {
tag: MyComponent
};
// 把Vnode 渲染为真实DOM
function render(vnode: any, container: any) {
// 根据vnode创建真实DOM并添加到容器中
if (typeof vnode.tag === 'string') {// html标签
mountElement(vnode, container);
} else { // 组件
mountComponent(vnode, container);
}
}
// 创建真实dom并添加到容器中
function mountElement(vnode: any, container: any) {
// 创建元素
const element = document.createElement(vnode.tag);
// 将元素添加到容器
container.appendChild(element);
}
// 创建组件
function mountComponent(vnode: any, container: any) {
console.log('componentVnode', componentVnode, new componentVnode.tag())
// 创建组件实例
const instance = new vnode.tag();
// 渲染
instance.$vnode = instance.render();
// 挂载
mountElement(instance.$vnode, container)
}
useEffect(() => {
// 调用render函数
render(elementVnode, document.getElementById('app'));
render(componentVnode, document.getElementById('app'))
}, []);
return (
<div id={'app'} className={"div"}>
divdivdiv
</div>
)
}