React基础-JSX的本质-虚拟DOM的创建过程实例分析

JSX的本质

实际上,jsx仅仅只是 React.createElement(component, props, ...children) 这个函数的语法糖

所有的jsx最终都会被转换成React.createElement的函数调用。

createElement需要传递三个参数:

参数一:type

当前元素的类型;

如果是标签元素,那么就使用字符串表示, 例如 “div”;

如果是组件元素,那么就直接使用组件的名称;

参数二:config

所有jsx中的属性都在config中以对象的属性和值的形式存储;

比如传入className作为元素的class;

参数三:children

存放在标签中的内容,以children数组的方式进行存储;

当然,如果是多个元素呢?React内部有对它们进行处理,处理的源码在下方

我们知道默认jsx是通过babel帮我们进行语法转换的,所以我们之前写的jsx代码都需要依赖babel; 我们可以在babel的官网中快速查看转换的过程: 链接: https://babeljs.io/repl/#?presets=react

例如有下面这样一段jsx代码

class App extends React.Component {
  constructor() {
    super()
  }
  render() {
    return (
      <div>
        <div className="header">Header</div>
        <div className="content">
          <div>Banner</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>
    )
  }
}
const app = ReactDOM.createRoot(document.querySelector("#app"))
app.render(<App/>)

那么也就是说我们可以自己来编写React.createElement代码:

我们没有通过jsx来书写了,界面依然是可以正常的渲染。

另外,在我们编写原生的React情况下,我们就不需要babel相关的内容了(当然真实开发中我们是不会编写原生的React的)

  • 所以,type="text/babel"可以被我们删除掉了;
  • 所以,<script src="../react/babel.min.js"></script>也可以被我们删除掉了;
<div></div>
<script src="../lib/../lib/react.js"></script>
<script src="../lib/react-dom.js"></script>
<script>
  class App extends React.Component {
    constructor() {
      super()
    }
    render() {
      const element = React.createElement("div", null, /*#__PURE__*/React.createElement("div", {
          className: "header"
        }, "Header"), /*#__PURE__*/React.createElement("div", {
          className: "content"
        }, /*#__PURE__*/React.createElement("div", null, "Banner"), /*#__PURE__*/React.createElement("ul", null, /*#__PURE__*/React.createElement("li", null, "\u8F6E\u64AD\u56FE1"), /*#__PURE__*/React.createElement("li", null, "\u8F6E\u64AD\u56FE2"), /*#__PURE__*/React.createElement("li", null, "\u8F6E\u64AD\u56FE3"), /*#__PURE__*/React.createElement("li", null, "\u8F6E\u64AD\u56FE4"), /*#__PURE__*/React.createElement("li", null, "\u8F6E\u64AD\u56FE5"))), /*#__PURE__*/React.createElement("div", {
          className: "footer"
        }, "Footer"));
        return element
    }
  }
  const app = ReactDOM.createRoot(document.querySelector("#app"))
  app.render(React.createElement(App, null))
</script>

虚拟DOM的创建过程

我们通过 React.createElement 最终创建出来一个 ReactElement对象:

这个ReactElement对象是什么作用呢?React为什么要创建它呢?

原因是React利用ReactElement对象组成了一个JavaScript的对象树;

JavaScript的对象树就是虚拟DOM(Virtual DOM);

如何查看ReactElement的树结构呢?

我们可以将上面代码中的jsx返回结果进行打印;

**而ReactElement最终形成的树结构就是虚拟DOM (Virtual DOM) **;

虚拟DOM帮助我们从命令式编程转到了声明式编程的模式

React官方的说法:Virtual DOM 是一种编程理念

在这个理念中,UI以一种理想化或者说虚拟化的方式保存在内存中,并且它是一个相对简单的JavaScript对象

我们可以通过root.render让 虚拟DOM 和 真实DOM同步起来,这个过程中叫做协调(Reconciliation);

这种编程的方式赋予了React声明式的API:

你只需要告诉React希望让UI是什么状态;

React来确保DOM和这些状态是匹配的;

你不需要直接进行DOM操作,就可以从手动更改DOM、属性操作、事件处理中解放出来;

PS:笔者在进行相关测试或开发的时候比较喜欢实用vite搭建vue或react的运行环境,使用命令 npm init vite@latest 创建基本的项目框架,再进行相关调试。

理解虚拟DOM有助于我们更加深入的理解react、vue等框架的运行原理。

(0)

相关推荐

  • react中的虚拟dom和diff算法详解

    虚拟DOM的作用 首先我们要知道虚拟dom的出现是为了解决什么问题的,他解决我们平时频繁的直接操作DOM效率低下的问题.那么为什么我们直接操作DOM效率会低下呢? 比如我们创建一个div,我们可以在控制台查看一下这个div上自带或者继承了很多属性,尤其是我们使用js操作DOM的时候,我们的DOM本身就很复杂,js的操作也会占用很多时间,但是我们控制不了DOM元素本身,因此虚拟DOM解决的是js操作DOM这一层面,其实解决的是减少了操作dom的次数 简单实现虚拟DOM 虚拟DOM,见名知意,就是假

  • React详细讲解JSX和组件的使用

    目录 一.React JSX 1.1 JSX简介 1.2 JSX表达式 1.3 JSX条件表达式 1.4 JSX循环表达式 1.5 JSX样式表达式 1.6 JSX注释表达式 二.React组件 2.1 类组件 2.2 函数组件 2.3 React Props 一.React JSX 1.1 JSX简介 JSX是全称是(JavaScript XML)按照React 官方的解释,JSX 是一个 JavaScript 的语法扩展,类似于模板语法,或者说是一个类似于 XML 的 ECMAScript

  • React之虚拟DOM的实现原理

    目录 React虚拟DOM机制 React diff 算法 1. 传统 diff 算法 2. react diff 算法 总结 最后 React虚拟DOM机制 虚拟DOM本质上是JavaScript对象,是对真实DOM的抽象 状态变更时,记录新树和旧树的差异 最后把差异更新到真正的dom中 React引入了虚拟DOM(Virtual DOM)的机制:在浏览器端用Javascript实现了一套DOM API. 基于React进行开发时所有的DOM构造都是通过虚拟DOM进行,每当数据变化时,Reac

  • 浅谈React的最大亮点之虚拟DOM

    在Web开发中,需要将数据的变化实时反映到UI上,这时就需要对DOM进行操作,但是复杂或频繁的DOM操作通常是性能瓶颈产生的原因,为此,React引入了虚拟DOM(Virtual DOM)的机制. 一.什么是虚拟DOM? 在React中,render执行的结果得到的并不是真正的DOM节点,结果仅仅是轻量级的JavaScript对象,我们称之为virtual DOM. 虚拟DOM是React的一大亮点,具有batching(批处理)和高效的Diff算法.这让我们可以无需担心性能问题而"毫无顾忌&q

  • Vue响应式原理与虚拟DOM实现步骤详细讲解

    目录 一.什么是响应式系统 二.实现原理 三.虚拟DOM实现 四.总结 一.什么是响应式系统 在Vue中,我们可以使用data属性来定义组件的数据.这些数据可以在模板中使用,并且当这些数据发生变化时,相关的DOM元素也会自动更新.这个过程就是响应式系统的核心.例如,我们在Vue组件中定义了一个count属性: <template> <div>{{ count }}</div> </template> <script> export default

  • vue 虚拟DOM快速入门

    虚拟 DOM 什么是虚拟 dom dom 是文档对象模型,以节点树的形式来表现文档. 虚拟 dom 不是真正意义上的 dom.而是一个 javascript 对象. 正常的 dom 节点在 html 中是这样表示: <div class='testId'> <p>你好</p> <p>欢迎光临</p> </div> 而在虚拟 dom 中大概是这样: { tag: 'div', attributes:{ class: ['testId']

  • React jsx转换与createElement使用超详细讲解

    目录 jsx的转换 16.x版本及之前 17.x版本及之后 React.createElement源码 React.Component 源码 总结 jsx的转换 我们从 react 应用的入口开始对源码进行分析,创建一个简单的 hello, world 应用: import React, { Component } from 'react'; import ReactDOM from 'react-dom'; export default class App extends Component

  • Vue源码分析之虚拟DOM详解

    为什么需要虚拟dom? 虚拟DOM就是为了解决浏览器性能问题而被设计出来的.例如,若一次操作中有10次更新DOM的动作,虚拟DOM不会立即操作DOM,而是将这10次更新的diff内容保存到本地一个JS对象中,最终将这个JS对象一次性attch到DOM树上,再进行后续操作,避免大量无谓的计算量.简单来说,可以把Virtual DOM 理解为一个简单的JS对象,并且最少包含标签名( tag).属性(attrs)和子元素对象( children)三个属性. ----- 元素节点: 元素节点更贴近于我们

  • Vue中简单的虚拟DOM是什么样

    目录 1. 一个简单的虚拟DOM长什么样 2. Vue中的虚拟DOM长什么样 3. Vue中的虚拟DOM实现 4. createTextVNode 1. 一个简单的虚拟DOM长什么样 其实当今前端框架不少用到了虚拟DOM的技术,但各家有各家的实现.这里我们先看下比较简单的虚拟DOM库snabbdom的虚拟DOM长什么样 我们假设有html如下,其实也就是所谓的真实DOM <div class="message">Hello World</div> 那么snabb

  • vue 虚拟DOM的原理

    为什么需要虚拟DOM? 如果对前端工作进行抽象的话,主要就是维护状态和更新视图,而更新视图和维护状态都需要DOM操作.其实近年来,前端的框架主要发展方向就是解放DOM操作的复杂性. 运行js的速度是很快的,大量的操作DOM就会很慢,时常在更新数据后会重新渲染页面,这样造成在没有改变数据的地方也重新渲染了DOM 节点,这样就造成了很大程度上的资源浪费. 在jQuery出现以前,我们直接操作DOM结构,这种方法复杂度高,兼容性也较差.有了jQuery强大的选择器以及高度封装的API,我们可以更方便的

  • 详解操作虚拟dom模拟react视图渲染

    1.为什么要使用虚拟dom? 网页性能优化->尽量少操作DOM 2..虚拟DOM(Virtual DOM) VS js直接操作原生DOM(innerHTML) function Raw() { var data = _buildData(), html = ""; ... for(var i=0; i<data.length; i++) { var render = template; render = render.replace("{{className}}&

  • Vue虚拟dom被创建的方法

    先来看生成虚拟dom的入口文件: ... import { parse } from './parser/index' import { optimize } from './optimizer' import { generate } from './codegen/index' ... const ast = parse(template.trim(), options) if (options.optimize !== false) { optimize(ast, options) } c

随机推荐