React.createElement()源码简易分析

618 阅读1分钟

当我们去写react应用程序时,会采用jsx语法来进行编写。

- 什么是jsx?

  • jsx就是一种将html和js混写在一起,将元素的结构、样式、属性等写在一块,这就是jsx。

举个栗子:

let element = <div className="box" style={{ color:'red' }}>hello world</div>

上面是我们通过jsx语法去创建了一个div元素,那这个element变量会返回一个虚拟dom也可以叫react元素。当我们编译的时候通过babel来转换成React.createElement工厂函数去构造一个虚拟dom。

jsx编译完等同于⬇️

React.createElement("div", {
  className: "box",
  style: {
    color: 'red'
  }
}, "hello world");

那么我们可以来实现createElement函数基本的逻辑



import {  REACT_ELEMENT } from "./contance"
import { warpToVdom } from "./utils"


/**
 * createElement 创建一个虚拟的dom元素也可以叫react元素
 * @param {*} type //标签类型
 * @param {*} config //
 * @param {*} children //儿子们
 */
function createElement(type,config,children){
    // debugger
    let key,ref
    if( config ){
        key = config.key
        ref = config.ref
        delete config.key
        delete config.ref
    }
    let props = {...config};
    //根据形参的个数来判断是否有多个子元素
    if( arguments.length > 3 ){
        // children变成一个数组
        // 如果children是文本或者数字则包装成一个对象,为了后期方便做DIFF优化
        props.children = Array.prototype.slice.call(2).map(warpToVdom)
    } else {
        // 如果children是文本或者数字则包装成一个对象,为了后期方便做DIFF优化
        props.children = warpToVdom(children);
    }
    return {
        $$typeof:REACT_ELEMENT,
        key,
        ref,
        props,
    }
    // 返回结果
    // {
    //     $$typeof: Symbol(react.element)  唯一标识
    //     key: null 做DIFF优化时用到的
    //     props: {className: 'title', style: {…}, children: 'hello'} 属性
    //     ref: null 可以通过ref来找到当前虚拟dom对应的真实dom元素
    //     type: "h1" 标签tagname
    //     ...
    // }

}


const React = {
    createElement
}
//导出React模块即可
export default React