构建本身的React:(2)Element creation and JSX

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。又由于我们之前定义了文本元素也须要有typeprops属性,所以我们会将刚传进来的字符串转成一个文本元素。

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});
}

上面代码排除了子元素为nullundefinedfalse的状况。这些状况都是没必要衬着的,所以也不须要增加到props.children上。

Summary

这一节我们依旧没有增加主功能到Didact上,但现在我们已开始运用JSX来建立元素了,这大幅提升了开辟体验。我已将上节和本节的代码在codepen上更新了。代码头部的解释/** @jsx crerateElement8/通知了babel去运用createElement来转义JSX。

你也能够在这里检察代码

下一节我们将往Didact中到场假造DOM和用来支撑更新操纵的一致性校验算法。

下一节

    原文作者:许三多
    原文地址: https://segmentfault.com/a/1190000017234521
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞