前言
最近正在学习,学习,还是学习。。。。越学习越觉得自己啥都不会,有点焦虑了。。。决定开始尝试写写博客文章,记录下学习过程,废话不说了,开始吧!
正文
React的jsx语法会通过babel编译成React.createElement(至于咋编译的我现在也不知道🐶)但是我们要实现一个这个方法需要让让jsx语法调用我们的createElement,需要对babel进行特殊配置,配置如下:
{
"presets": [
"@babel/preset-env",
[
"@babel/preset-react",
{
"pragma": "MiniReact.createElement" //重点在这
}
]
]
}
官方文档createElement参数如下:
- type:标签名称或者React组件类型
- props:组件或者节点上的参数比如class等
- children:子节点
一、乞丐版
那么我们基本参数就根据文档定义,同样接收三个参数,并且将他们直接返回出去,而且我们可以通过props访问到children,将children添加到props中去
function createElement(type, props, ...children) {
return {
type,
props: { ...props, children}
children
}
}
返回是这样婶的(通过配置babel,调用我们自己的createElement)
呃。。。。。好像有点不太对(乞丐版就别纠结那么多了)。。。。虚拟DOM的本质上一个对象,但是上面也不是对象,而且对于布尔值不应该渲染在视图内,所以这个时候需要进行特殊处理下。有了下面的升级版
二、升级版
需要考虑下面场景
- 直接是一个文本节点,那么此时需要将文本转化成一个对象
- 在编写过程中,一些节点是bool值或者是null,需要将这部分值去除
先考虑第一种情况,这个时候我们需要对children参数进行遍历,判断是不是对象即可!(好像解决了第一种情况)
function createElement(type, props, ...children) {
const childrenItems = [].concat(children).reduce((result, item) => {
if (item instanceof Object) {
result.push(item)
} else {
result.push(createElement('text', { textContent: item }))
}
return result
},[])
return {
type,
props: { ...props, children: childrenItems},
children: childrenItems
}
至于第二种情况,我们需要过滤将children中的bool类型值过滤出去就好,那么如果item值 不是布尔类型或者null的时候,不去执行上面代码中的对result添加值即可
function createElement(type, props, ...children) {
const childrenItems = [].concat(children).reduce((result, item) => {
if (item !== false && item!==null && item!==true) {
if (item instanceof Object) {
result.push(item)
} else {
result.push(createElement('text', { textContent: item }))
}
}
return result
},[])
return {
type,
props: { ...props, children: childrenItems},
children: childrenItems
}
}
先暂时进行到这,未完继续(困了,该睡觉了,虽然有点焦虑,身体重要,拒绝内卷)