美文网首页
JSX 代码是如何“摇身一变”成为 DOM 的?

JSX 代码是如何“摇身一变”成为 DOM 的?

作者: 米古月_f198 | 来源:发表于2021-03-01 09:43 被阅读0次
    import React from "react";
    import ReactDOM from "react-dom";
    class App extends React.Component {
      render() {
        return (
          <div className="App">
            <h1 className="title">I am the title</h1>
            <p className="content">I am the content</p>
          </div>
        );
      }
    }
    const rootElement = document.getElementById("root");
    ReactDOM.render(<App />, rootElement);
    

    “JSX 是 JavaScript 的一种语法扩展,它和模板语言很接近,但是它充分具备 JavaScript 的能力。”

    Facebook 公司给 JSX 的定位是 JavaScript 的“扩展”,而非 JavaScript 的“某个版本”,这就直接决定了浏览器并不会像天然支持 JavaScript 一样地支持 JSX。JSX 会被编译为 React.createElement(), React.createElement() 将返回一个叫作“React Element”的 JS 对象。“编译”这个动作,是由 Babel来完成的。Babel 具备将 JSX 语法转换为 JavaScript 代码的能力。

    image.png

    可以看到,所有的 JSX 标签都被转化成了 React.createElement 调用,这也就意味着,我们写的 JSX 其实写的就是 React.createElement,虽然它看起来有点像 HTML,但也只是“看起来像”而已。JSX 的本质是React.createElement这个 JavaScript 调用的语法糖,这也就完美地呼应上了 React 官方给出的“JSX 充分具备 JavaScript 的能力”这句话。

    JSX 代码层次分明、嵌套关系清晰;而 React.createElement 代码则给人一种非常混乱的“杂糅感”,这样的代码不仅读起来不友好,写起来也费劲。
    JSX 语法糖允许前端开发者使用我们最为熟悉的类 HTML 标签语法来创建虚拟 DOM,在降低学习成本的同时,也提升了研发效率与研发体验。

    (1) **createElement 入参 **

    export function createElement(type, config, children)

    React.createElement("ul", {
      // 传入属性键值对
      className: "list"
       // 从第三个入参开始往后,传入的参数都是 children
    }, React.createElement("li", {
      key: "1"
    }, "1"), React.createElement("li", {
      key: "2"
    }, "2"));
    

    对应

    <ul className="list">
      <li key="1">1</li>
      <li key="2">2</li>
    </ul>
    

    可以看到:createElement 有 3 个入参,这 3 个入参囊括了 React 创建一个元素所需要知道的全部信息。
    type:用于标识节点的类型。它可以是类似“h1”“div”这样的标准 HTML 标签字符串,也可以是 React 组件类型或 React fragment 类型。
    config:以对象形式传入,组件所有的属性都会以键值对的形式存储在 config 对象中。
    children:以对象形式传入,它记录的是组件标签之间嵌套的内容,也就是所谓的“子节点”“子元素”。

    image.png

    (2)出参解读:初识虚拟 DOM
    上面已经分析过,createElement 执行到最后会 return 一个针对 ReactElement 的调用。依旧事先看一看关于 ReactElement的源码 + 注释形式的解析:
    ReactElement 的代码出乎意料的简短,从逻辑上可以看出,ReactElement 其实只做了一件事情,那就是“创建”,说得更精确一点,是“组装”:ReactElement 把传入的参数按照一定的规范,“组装”进了 element 对象里,并把它返回给了 React.createElement,最终 React.createElement 又把它交回到了开发者手中

    (3)虚拟DOM渲染
    这个 ReactElement 对象实例,本质上是以 JavaScript 对象形式存在的对 DOM 的描述,也就是老生常谈的“虚拟 DOM”(准确地说,是虚拟 DOM 中的一个节点。关于虚拟 DOM, 后续专栏的“模块二:核心原理”中将会花大量的篇幅来研究它,此处只需要能够结合源码,形成初步认知即可)。
    既然是“虚拟 DOM”,那就意味着和渲染到页面上的真实 DOM 之间还有一些距离,这个“距离”,就是由大家喜闻乐见的ReactDOM.render方法来填补的。

    ReactDOM.render(
        // 需要渲染的元素(ReactElement)
        element, 
        // 元素挂载的目标容器(一个真实DOM)
        container,
        // 回调函数,可选参数,可以用来处理渲染结束后的逻辑
        [callback]
    )
    
    const rootElement = document.getElementById("root");
    ReactDOM.render(<App />, rootElement);
    
    image.png

    作者:啊丫丫
    链接:https://juejin.cn/post/6916009337953615886
    来源:掘金
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    相关文章

      网友评论

          本文标题:JSX 代码是如何“摇身一变”成为 DOM 的?

          本文链接:https://www.haomeiwen.com/subject/xwvofltx.html