美文网首页
jsx(6)-本质和原理

jsx(6)-本质和原理

作者: 未路过 | 来源:发表于2022-11-09 20:57 被阅读0次
    image.png

    babel每遇到一个标签(div,span之类的html标签,或者是组件名字<App/>),就会将里面它转换成React.createElement()这个函数的调用。

    image.png

    React.createElement("div", {className: "header"}, React.createElement(...))创建出来的对象,就是虚拟dom。
    然后再根据虚拟dom,生成真实dom。

          // 1.定义App根组件
          class App extends React.Component {
            constructor() {
              super();
              this.state = {
                message: "Hello World",
              };
            }
    
            render() {
              const { message } = this.state;
    
              return (
                <div>
                  <div className="header">Header</div>
                  <div className="Content">
                    <div>{message}</div>
                    <ul>
                      <li>列表数据1</li>
                      <li>列表数据2</li>
                      <li>列表数据3</li>
                      <li>列表数据4</li>
                      <li>列表数据5</li>
                    </ul>
                  </div>
                  <div className="footer">Footer</div>
                </div>
              );
            }
          }
    
          // 2.创建root并且渲染App组件
          const root = ReactDOM.createRoot(document.querySelector("#root"));
          root.render(<App />);
    
    "use strict";
    
    // 1.定义App根组件
    class App extends React.Component {
      constructor() {
        super();
        this.state = {
          message: "Hello World"
        };
      }
      render() {
        const { message } = this.state;
        return /*#__PURE__*/ React.createElement(
          "div",
          null,
          /*#__PURE__*/ React.createElement(
            "div",
            {
              className: "header"
            },
            "Header"
          ),
          /*#__PURE__*/ React.createElement(
            "div",
            {
              className: "Content"
            },
            /*#__PURE__*/ React.createElement("div", null, message),
            /*#__PURE__*/ React.createElement(
              "ul",
              null,
              /*#__PURE__*/ React.createElement(
                "li",
                null,
                "\u5217\u8868\u6570\u636E1"
              ),
              /*#__PURE__*/ React.createElement(
                "li",
                null,
                "\u5217\u8868\u6570\u636E2"
              ),
              /*#__PURE__*/ React.createElement(
                "li",
                null,
                "\u5217\u8868\u6570\u636E3"
              ),
              /*#__PURE__*/ React.createElement(
                "li",
                null,
                "\u5217\u8868\u6570\u636E4"
              ),
              /*#__PURE__*/ React.createElement(
                "li",
                null,
                "\u5217\u8868\u6570\u636E5"
              )
            )
          ),
          /*#__PURE__*/ React.createElement(
            "div",
            {
              className: "footer"
            },
            "Footer"
          )
        );
      }
    }
    
    // 2.创建root并且渲染App组件
    const root = ReactDOM.createRoot(document.querySelector("#root"));
    root.render(/*#__PURE__*/ React.createElement(App, null));
    
    

    React.createElement(component, props, ...children)
    这个children也是React.createElement()。
    逗号分开。
    /#PURE/
    babel告诉你这个函数是纯函数调用。可以在webpack的tree-shaking里面被摇掉。不用的话,这个函数将不会被打包

    jsx本质,将标签转换成Reac.createElement()函数。

    Reac.createElement()函数创建出来的是ReactElement对象

    虚拟dom的创建原理

    image.png
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>计数器</title>
      </head>
      <body>
        <div id="root"></div>
    
        <script src="../lib/react.js"></script>
        <script src="../lib/react-dom.js"></script>
    
        <script>
          // 1.定义App根组件
          class App extends React.Component {
            constructor() {
              super();
              this.state = {
                message: "Hello World",
              };
            }
    
            render() {
              const { message } = this.state;
              const element = React.createElement(
                "div",
                null,
                /*#__PURE__*/ React.createElement(
                  "div",
                  {
                    className: "header",
                  },
                  "Header"
                ),
                /*#__PURE__*/ React.createElement(
                  "div",
                  {
                    className: "Content",
                  },
                  /*#__PURE__*/ React.createElement("div", null, message),
                  /*#__PURE__*/ React.createElement(
                    "ul",
                    null,
                    /*#__PURE__*/ React.createElement(
                      "li",
                      null,
                      "\u5217\u8868\u6570\u636E1"
                    ),
                    /*#__PURE__*/ React.createElement(
                      "li",
                      null,
                      "\u5217\u8868\u6570\u636E2"
                    ),
                    /*#__PURE__*/ React.createElement(
                      "li",
                      null,
                      "\u5217\u8868\u6570\u636E3"
                    ),
                    /*#__PURE__*/ React.createElement(
                      "li",
                      null,
                      "\u5217\u8868\u6570\u636E4"
                    ),
                    /*#__PURE__*/ React.createElement(
                      "li",
                      null,
                      "\u5217\u8868\u6570\u636E5"
                    )
                  )
                ),
                /*#__PURE__*/ React.createElement(
                  "div",
                  {
                    className: "footer",
                  },
                  "Footer"
                )
              );
              console.log(element);
    
              return element;
            }
          }
    
          // 2.创建root并且渲染App组件
          const root = ReactDOM.createRoot(document.querySelector("#root"));
          root.render(React.createElement(App, null));
        </script>
      </body>
    </html>
    
    
    image.png

    原因是React利用ReactElement对象组成了一个JavaScript的对象树;(reactElement对象, 这个对象有props属性,里面存放着children的reatElement对象,是树结构)
     JavaScript的对象树就是虚拟DOM(Virtual DOM);

    虚拟dom转换成真实dom

    babel将标签转换成react.createElement的函数调用。然后浏览器执行的时候,会得到react Element对象,也就是js对象。这些js对象,经过渲染,就会变成真实dom。

    vue的化里面的template里面有很多指令,v-for,v-bind之类的也得解析,react中的解析更见简单明了,而且vue的template是vue自己解析的。react的jsx是babel解析的。

    虚拟dom的作用(面试题)

    1.没有必要重新渲染所有的真实dom。
    在虚拟dom里面快速进行diff算法,来决定到底哪些东西更新,哪些东西不更新。(虚拟dom比较简单,真实的dom有很多方法之类的,很占内存空间。)
    2.可以做跨平台应用程序。
    虚拟dom的本质是js对象。react可以将虚拟dom渲染成真实dom。也是通过document.createElement方法渲染到web的dom上面的。ratct里面有个技术叫做react native,它可以渲染成ios,安卓上面的控件,用react开发原生的东西。


    image.png

    声明式编程

    image.png

    我们最主要是在做的事情是在维护这个状态,你只需要告诉我你希望界面长什么样子,然后维护着你这里这个状态就可以了.然后呢,当状态发生改变的时候,你调这个setState,告诉我状态发生改变了,我重新渲染,那么真实的到底它的DOM如何更新,不需要你来做。

    在react中是没有数据劫持的,是需要手动调用setState函数更新界面。vue中有数据劫持,当数据改变的时候,自动渲染页面。

    相关文章

      网友评论

          本文标题:jsx(6)-本质和原理

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