当我们去写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