React中的jsx语法转换后生成虚拟DOM,再挂载到真实的DOM中的全过程讲解

news/2024/11/22 8:27:28/

前言

react中的jsx语法很多伙伴都会使用,

  • 但是你知道它的本质是什么吗?运行中它会做如何的转换呢?
  • jsx内部又是怎么生成了虚拟DOM
  • 虚拟DOM又是如何挂载到真实DOM上去的呢?

带着这些问题,我们做个讲解把,相信深度了解本文后,肯定会jsx、虚拟DOM有进一步的理解

1、react中的jsx语法

  • 简单的jsx语法, 就是再js中写html元素,前提是script标签必须加 type=text/babel, 否则jsx语法会报错
    在这里插入图片描述

  • jsx 仅仅只是 React.createElement(component, props, ...children) 函数的语法糖

    const msg1 = <h2>哈哈哈</h2>
    

    js中上面这段代码等价于下面这段react.createElement()的值

    const msg2 = React.createElement("h2", null, "哈哈哈");//js语法
    

2、 jsx语法在babel中会转成 React.createElement()的函数调用。

注意:使用了React相关的方法一定先引入react.development.js 和react-dom.development.js这两个文件,否则会报错

<script src="../react/react.development.js"></script>
<script src="../react/react-dom.development.js"></script>

3、babel转换

  • 我们先用jsx语法, 开发页面。部分html代码省略,只写核心js代码

    <script src="../react/react.development.js"></script>
    <script src="../react/react-dom.development.js"></script>
    //babel.min文件 是将 jsx转成 React.createElement函数调用的
    <script src="../react/babel.min.js"></script>
    <script type='text/babel'>
    // 这是jsx语法
    const msg1 = <div class="header"><h2>头部</h2><div class="main">主题</div><footer>这里是尾部</footer></div>;ReactDOM.render(msg1, document.getElementById("app"));
    </script>
    

    用浏览器打开文件,查看页面效果

    在这里插入图片描述

  • 然后我们在把上面的jsx代码转成 React.createElement函数的形式

  • 可以在babel的官网中快速查看转换的过程。babel官网链接:https://babeljs.io/repl/#?presets=react

在这里插入图片描述

  • 复制右边转换后的React.createElement函数调用代码到js中

    <script src="../react/react.development.js"></script>
    <script src="../react/react-dom.development.js"></script>
    // type="text/babel" 可以去掉,babel.min.js 也可以不用了。
    // 因为我们代码中没有了jsx语法了。下面的代码属于正常的js代码
    <script>
    const msg2 = React.createElement("div", {class: "header"
    }, React.createElement("h2", null, "\u5934\u90E8"), React.createElement("div", {class: "main"
    }, "\u4E3B\u9898"), React.createElement("footer", null, "\u8FD9\u91CC\u662F\u5C3E\u90E8"));
    //React.reder 函数渲染到浏览器上
    ReactDOM.render(msg2, document.getElementById("app"));
    </script>
    

    在浏览器中打开后,查看页面
    在这里插入图片描述

  • jsx语法和React.createElement函数的方法都可以得到相同的结果,渲染在页面的正是DOM也是一样的。

  • 所以我们可以得出结论:jsx 仅仅只是 React.createElement(component, props, ...children) 函数的语法糖

  • 在真实开发中我们不会使用React.createElement函数的方式写代码,因为可读性太差了,代码量又多,难维护,我们更喜欢使用jsx语法来编写代码

  • React.render函数是怎样把createElement函数的返回值挂载到DOM上的呢?

4、虚拟DOM的创建过程

  • React.createElement 最终创建出来一个 ReactElement对象

    1. 在上面的React.createElement函数调用后,打印它的返回值

      const msg2 = React.createElement("div", {class: "header"},React.createElement("h2", null, "\u5934\u90E8"), React.createElement("div", {class: "main"}, "\u4E3B\u9898"), React.createElement("footer", null, "\u8FD9\u91CC\u662F\u5C3E\u90E8"));console.log(msg2);
      ReactDOM.render(msg2, document.getElementById("app"));
      

      在浏览器打开,查看结果
      在这里插入图片描述

      msg2就是一个object对象,对象的第一层是html中的最外层class等于headerdivdiv里面的三个子元素,放在对象中的props对象中的children数组中一一对应。如果h2标签中还有子元素,那h2对象中的props对象中的children数组又会有objectd对象,… 这将一层一层的往下套

  • React利用ReactElement对象组成了一个JavaScript的对象树

    1. msg2就是调用React.createElement函数时候,通过ReactElement函数转成一个JavaScript对象树的

    2. react源码下/packages/react/index.js文件找到了createElement函数,它是 ./src/React文件下导出的
      在这里插入图片描述

    3. 找到react文件,发现它是 ./ReactElement文件下导出的

      在这里插入图片描述

    4. 找到ReactElement文件,里面有一个createElement函数,在js中本质上就是在调用这个函数

      在这里插入图片描述
      在这里插入图片描述

    5. 它又调用了另一个ReactElement函数

      在这里插入图片描述

      在这里插入图片描述

    6. 这个ReactElement函数返回是一个object对象,这个对象就是我们在浏览器打印出来的那个msg2, 它就是javascript对象树

  • JavaScript的对象树就是大名鼎鼎的虚拟DOM

    1. 有了虚拟DOM,那怎么把虚拟DOM映射到真实的DOM上呢?

    2. react是通过ReactDOM.render 函数把虚拟DOM挂载到真实DOM

      //把虚拟DOM挂载到 id为app的元素中
      ReactDOM.render(msg2, document.getElementById("app"));
      

      在这里插入图片描述

5、为什么要使用虚拟DOM

  • 很难跟踪状态发生的改变:原有的开发模式,我们很难跟踪到状态发生的改变,不方便针对我们应用程序进行调试
  • 操作真实DOM性能较低:传统的开发模式会进行频繁的DOM操作,而这一的做法性能非常的低

http://www.ppmy.cn/news/22768.html

相关文章

python图形化开发教程

简介学习此教程必须先学习python入门教程&#xff08; Python入门教程_恰到好处a的博客-CSDN博客&#xff09;PySimpleGUI这个模块需要安装&#xff0c;在cmd输入pip install PySimpleGUI&#xff0c;在python中验证安装:输入import PySimpleGUI&#xff0c;看一看是否正常引入…

Android boot.img dtb.img 编译过程

最近做RK3588案子,修改dts后,导致boot.img过大,编译出错,整体分析下boot.img过大的原因是因为在打包boot.img过程中,dbt.img过大导致,所以整体分析下boot.img编译过程,尤其是dbt.img的生成过程.boot.img生成过程在Andorid跟目录下执行, source build/envsetup.sh 然后lunch xx(…

科技云报道:上云尚未成功,“下云潮”已悄然来临?

科技云报道原创。 云计算一直被视为是企业数字化转型的底座&#xff0c;很多企业都在通过加速数字化转型应对市场环境的动荡变化&#xff0c;一手抓降本增效&#xff0c;另一手也还在继续谋求突破式创新。 然而&#xff0c;经历这两年的疫情&#xff0c;活下去成为每一个企业的…

GBDT+LR算法解析及Python实现

1. GBDT LR 是什么 本质上GBDTLR是一种具有stacking思想的二分类器模型&#xff0c;所以可以用来解决二分类问题。 。 2. GBDT LR 用在哪 GBDTLR 使用最广泛的场景是CTR点击率预估&#xff0c;即预测当给用户推送的广告会不会被用户点击。 点击率预估模型涉及的训练样本一…

Python迭代器及其用法

从字面来理解&#xff0c;迭代器指的就是支持迭代的容器&#xff0c;更确切的说&#xff0c;是支持迭代的容器类对象&#xff0c;这里的容器可以是列表、元组等这些 Python 提供的基础容器&#xff0c;也可以是自定义的容器类对象&#xff0c;只要该容器支持迭代即可。如果要自…

【算法基础】归并排序解析

作者&#xff1a;柒号华仔 个人主页&#xff1a;欢迎访问我的主页 个人信条&#xff1a;星光不问赶路人,岁月不负有心人。 个人方向&#xff1a;专注于5G领域&#xff0c;同时兼顾其他网络协议&#xff0c;编解码协议&#xff0c;C/C&#xff0c;linux等&#xff0c;感兴趣的小…

【黑马SpringCloud(5)】es基础语法

Elasticsearch初识elasticsearchelasticsearch和lucene正向/倒排索引正向和倒排elasticsearch的一些概念分词器索引库操作文档操作查询文档查询所有全文检索精确查询range查询地理查询复合查询算分函数查询布尔查询搜索结果处理排序分页分页问题高亮总结初识elasticsearch ela…

ubuntu22.04安装mysql

sudo apt install mysql-server登录mysql sudo mysql -u root -p新增用户 CREATE USER admin% IDENTIFIED BY pass12345;grant all privileges on *.* to admin%;--------------以下没用-------------------- 方法一&#xff1a;默认账户登录 查看密码使用sudo cat /etc/mys…