从min-react 的学习中,了解如下知识:
- jsx 本质是什么?
- 树形结构如何渲染?–递归
- 基于观察者模式实现事件机制?
- 批处理机制 setState 是同步还是异步?
const reactElement = Symbol('react.element');
const reactText = Symbol("react.text");
function createElement(type, props, ...child) {
delete props.__self; //打包时自带
delete props.__source;//打包时自带
let children = child.flat(Infinity);
children = children.map(item => {
if (typeof item === 'object') {
return item;
} else if (typeof item === 'number' || typeof item === 'string') {
return {
$$typeof: reactText,
type: "textNode",
inner: item,
}
}
}).filter(item=>item)//去掉空数组、字符串、undefiend、null
return {
$$typeof:reactElement,
type,
props,
children
}
}
import {
reactElement, reactText } from './react';
function render(tree, container, cb) {
//核心方法(vnode,container,callback)
// dom元素如何渲染?
const node = createNode(tree);//递归树形结构
container.appendChild(node);
}
// 负责将虚拟dom ,渲染为真实dom,
function createNode(vnode) {
// 1.元素
// 2.文本节点
// 3.类组件(类、函数)
let node;
if (vnode.$$typeof === reactElement) {
// node = document.createElement(vnode.type);
// // // // 元素应该有相关的属性和children
// createProps(node, vnode.props);
// createChildren(node,vnode.children)
if (typeof vnode.type === 'string') {
//标签
node = document.createElement(vnode.type);
// 元素应该有相关的属性和children
createProps(node, vnode.props);
createChildren(node,vnode.children)
} else {
//组件
if (vnode.type.isReactComponent) {
node = createCmp(vnode)
}
}
} else if (vnode.$$typeof === reactText) {
node = document.createTextNode(vnode.inner);
}
return node;
}
// let eventNames = ['onClick', 'onMouseMove'];
// // 负责给元素添加属性
function createProps(node,props) {
// console.log(node, props,'props')
for (let s in props) {
if (s === 'style') {
for (let styl in props['style']) {
node['style'][styl] =props['style'][styl]
}
} else if (s.slice(0, 2) === 'on') {
// 在 React 中用的合成事件,React 基于观察者模式自己实现的一套事件机制
node[s.toLocaleLowerCase()] = props[s];//React中的事件是驼峰命名的写法,需要转化成小写完成事件的绑定: onClick => onclick
} else {
//举例。其他情况暂时就不考虑,属性直接加上
node[s] = props[s];
}
}
}
// // // 负责渲染子元素
function createChildren(parent,children) {
children.forEach(ele => {
render(ele, parent);
})
}
function stateFromProps(cmp, props, state) {
return cmp.type.getDerivedStateFromProps ? cmp.type.getDerivedStateFromProps(props, state) : {
}
}
// // // // React 组件渲染
function createCmp(vCmp) {
let Cmp = new vCmp.type(vCmp.props);//实例化
// 生命周期
let nextState = stateFromProps(vCmp, vCmp.props, vCmp.state)
if (nextState) {
Cmp.state = Object.assign(Cmp.state,nextState)
}
let vnode = Cmp.render();//生成虚拟dom
let node = createNode(vnode);//真实dom
Object.assign(nextState,nextState)
return node;
}
const ReactDOM = {
render
};
export default ReactDOM;
setState
在 React 事件,及相关的 React 方法中,是异步
在 setTimeout等异步方法,或DOM原生事件中,是同步