前端
这是我们手写react的第二季,这篇文章还是非常浅显易懂的,大家学习以后可以讲给不会的人听,那样学习效率会更高
createElement函数
让我们继续我们的应用程序,这次我们将替换react代码为我们自己的react版本
我们将开始写我们自己的createElement
。
让我们转换这个jsx为js,所以我们可以看到这个createElement方法的调用。
js
const element = React.createElement(
"div",
{ id: "foo" },
React.createElement("a", null, "bar"),
React.createElement("b")
)
正如前面步骤中看到的,element是一个具有type和props的对象。我们的函数仅仅需要做的是创建这个对象。
我们对props使用展开运算符,对子元素使用剩余参数语法,这样子元素属性将始终是一个数组。
例如:
createElement("div")
返回
js
{
"type": "div",
"props": { "children": [] }
}
createElement("div", null, a)
返回
js
{
"type": "div",
"props": { "children": [a] }
}
createElement("div", null, a, b)
返回:
json
{
"type": "div",
"props": { "children": [a, b] }
}
children 数组也可以包含原始的值像字符串和数字。所以我们将包裹不是一个对象的内容在他自己的元素内,并且对他们创建一个特殊的类型:TEXT_ELEMENT
当children为空的时候,react并不会包裹原始的值或者创建一个空数组,但是这样做可以使我们简化代码,对于我们的库,我们更喜欢简单的代码,而不是性能好的代码。
我们将使用react的createElement
。
为了代替他,让我们赐予我们库一个名字。我们需要一个听起来像react的名字。
我们可以叫他Didact
。
js
const Didact = {
createElement,
}
但是我们仍然想要在这里使用JSX。我们如何告诉babel去使用Didact的createElement替换React的createElement呢?
如果我们有一个像这样的注释
js
/** @jsx Didact.createElement */
const element = (
<div id="foo">
<a>bar</a>
<b />
</div>
)
那么babel编译这个jsx的时候将使用我们定义的方法