资讯专栏INFORMATION COLUMN

构建自己的React:(2)Element creation and JSX

Jensen / 1331人阅读

摘要:翻译自这里上一节我们介绍了,使用了一种很麻烦的方法来代表要渲染的。这一节我们将介绍如何使用来创建。上面代码排除了子元素为,和的情况。代码头部的注释告诉了去使用来转义。下一节我们将往中加入虚拟和用来支持更新操作的一致性校验算法。

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 = (
  
bar alert("Hi")}>click me
);

如果你对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://www.ucloud.cn/yun/99668.html

相关文章

  • React官网RECENT POSTS阅读

    摘要:事件行为在浏览器中保持一次,并且符合标准。主要是进行修复。事件已经在移动上支持。阻止已经在上存在的事件错误处理。然后对应的将会被打包送往客户端。在中弃用,现在正式删除。是运行于一个严格的安全策略下成为可能。增加警告提示非生产环境。 ⭐️写在开头 阅读React官网的 RECENT POSTS的个人翻译/摘要(部分)。 英文片段为官网原文片段。 原文地址 ⭐️为什么要使用React ...

    Sike 评论0 收藏0
  • JavaScript 是如何工作:编写自己 Web 开发框架 + React 及其虚拟 DOM

    摘要:与大多数全局对象不同,没有构造函数。为什么要设计更加有用的返回值早期写法写法函数式操作早期写法写法可变参数形式的构造函数一般写法写法当然还有很多,大家可以自行到上查看什么是代理设计模式代理模式,为其他对象提供一种代理以控制对这个对象的访问。 这是专门探索 JavaScript 及其所构建的组件的系列文章的第 19 篇。 如果你错过了前面的章节,可以在这里找到它们: 想阅读更多优质文章请...

    余学文 评论0 收藏0
  • React入门0x003:jsx 和自由组件

    摘要:概述说起来,我喜欢的还是他的思想,在中,实际上没有的区别,全部都是,就和一样,可以将所有的资源等同视之。但是这时候又出来说,我要把写在中,真是烦透咯不过,这种东西不过是年一轮回,就和时尚一样。 0x000 概述 说起来react,我喜欢的还是他的思想,在react中,实际上没有html、css、js的区别,全部都是js,就和webpack一样,可以将所有的资源等同视之。但是这在一开始,...

    eechen 评论0 收藏0
  • 说说对JSX认识

    摘要:认识引子最近几个月做的一个项目,使用了技术体系,自然而然的用到了。下面就总结一下自己对的认识。而这无疑增加了框架的门槛和复杂度。在被渲染之前,所有的数据都被转义成为了字符串处理。以避免跨站脚本攻击。表示对象将编译成调用。 JSX认识 引子 最近几个月做的一个项目,使用了react技术体系,自然而然的用到了JSX。下面就总结一下自己对JSX的认识。 什么是JSX 即JavaScript...

    clasnake 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<