min-react学习笔记

本文介绍了React的核心概念,包括jsx的本质——一种用于创建虚拟DOM的语法糖,树形结构的渲染方法,以及React如何基于观察者模式实现事件机制。同时,文章探讨了setState的批处理机制,指出其在不同场景下可能是同步或异步的。此外,还详细展示了React元素和文本的创建过程,以及虚拟DOM到真实DOM的转换方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

从min-react 的学习中,了解如下知识:

  1. jsx 本质是什么?
  2. 树形结构如何渲染?–递归
  3. 基于观察者模式实现事件机制?
  4. 批处理机制 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原生事件中,是同步

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值