Didact: Element creation and JSX
翻译自这里:https://engineering.hexacta.c…
JSX
上一节我们引见了Didact Elements,运用了一种很贫苦的要领来代表要衬着的DOM。这一节我们将引见怎样运用JSX来建立Didact Elements。
下面是一个Didact Elements的原生对象示意:
const element = {
type: "div",
props: {
id: "container",
children: [
{ type: "input", props: { value: "foo", type: "text" } },
{
type: "a",
props: {
href: "/bar",
children: [{ type: "TEXT_ELEMENT", props: { nodeValue: "bar" } }]
}
},
{
type: "span",
props: {
onClick: e => alert("Hi"),
children: [{ type: "TEXT_ELEMENT", props: { nodeValue: "click me" } }]
}
}
]
}
};
有了JSX这个语法糖以后我们就能够运用下面这个要领来建立和上面一样的元素:
const element = (
<div id="container">
<input value="foo" type="text" />
<a href="/bar">bar</a>
<span onClick={e => alert("Hi")}>click me</span>
</div>
);
假如你对JSX不熟悉你能够能会想上面这段代码是个无效的JS对象—–没错,你想的是对的。为了让浏览器能剖析JSX,我们须要运用预处理器(比方babel,想对JSX有更多相识的能够看这里)来将JSX转换一下。比方babel会将上面的JSX转成下面这个模样:
const element = createElement(
"div",
{ id: "container" },
createElement("input", { value: "foo", type: "text" }),
createElement(
"a",
{ href: "/bar" },
"bar"
),
createElement(
"span",
{ onClick: e => alert("Hi") },
"click me"
)
);
剩下我们要做的就是增加一个createElement
要领来让Didact支撑JSX,其他的事情就能够交给预处理器了。createElement
要领的第一个参数是元素的范例type
,第二个参数是元素的props对象,剩下的其他参数就是children
了。createElement
要领会返回带有type
属性和props
属性的对象,props
属性值也是一个对象,该对象含有第二个参数的一切属性,第二个参数以后的其他参数会放在一个数组中,并作为该对象的children
属性值。来完成一下createElement
要领:
function createElement(type, config, ...args){
const props = Object.assign({}, config);
const hasChildren = args.length > 0;
props.children = hasChildren ? [].concat(...args) : [];
return {type, props}
}
上面的createElement
在不碰到文本元素时都能很好的事情。碰到文本元素时,文本内容会以字符串情势在第二个参数以后传递给createElement
。又由于我们之前定义了文本元素也须要有type
和props
属性,所以我们会将刚传进来的字符串转成一个文本元素。
const TEXT_ELEMENT = 'TEXT_ELEMENT';
function createElement(type, config, ...args){
const props = Object.assign({}, config);
const hasChildren = args.length > 0;
const rawChildren = hasChildren ? [].concat(...args) : [];
props.children = rawChildren.filter(c => c != null && c !== false)
.map(c => c instanceof Object ? c : createTextElement(c));
return { type, props };
}
function createTextElement(value){
return createElement(TEXT_ELEMENT, { nodeValue: value});
}
上面代码排除了子元素为null
, undefined
和false
的状况。这些状况都是没必要衬着的,所以也不须要增加到props.children
上。
Summary
这一节我们依旧没有增加主功能到Didact上,但现在我们已开始运用JSX来建立元素了,这大幅提升了开辟体验。我已将上节和本节的代码在codepen上更新了。代码头部的解释/** @jsx crerateElement8/
通知了babel去运用createElement
来转义JSX。
你也能够在这里检察代码。
下一节我们将往Didact中到场假造DOM和用来支撑更新操纵的一致性校验算法。