🧬 最低级别的 JSX

2025-06-07

🧬 最低级别的 JSX

这篇文章是即将发布的 JSX 文章的先行者

我们都听说过 JSX 是 React 用来渲染组件的特定 JavaScript 语法。好吧,我想说 JSX 就是 JavaScript 中的 HTML。或者说是Java - S cript -X ml 😂 因为 HTML 是 XML 的兄弟,也是SGML的子类。又或者,它只是Java - S cript- X的变体。

当有人问我什么是 React 时?我会告诉他们,React 只是一些返回 HTML 的 JavaScript 函数。它本质上是一个模板引擎。

function Component() {
/* ^^^^^^^^^^^^^^^^ */
/*   ^^^ JavaScript */

  return <div className="yay">lorem ipsum</div>
         /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
         /*       ^^^ HTML                   */
}
Enter fullscreen mode Exit fullscreen mode

草案:JSX 规范
XML 类语法扩展至 ECMASCRIPT
http://facebook.github.io/jsx/

好的,但是 HTML 语法只允许在 DOM 中使用,浏览器 JavaScript 不支持它。所以这意味着我们需要将其编译成浏览器支持的代码。

JSX 只是一些编译为有效 JavaScript 的语法糖。

什么是 JSX Pragma?
https://www.gatsbyjs.com/blog/2019-08-02-what-is-jsx-pragma/
https://babeljs.io/docs/en/babel-plugin-transform-react-jsx#pragma

目前它编译成类似这样的内容。

function Component() {
  return React.createElement("div", { className: "yay" }, "lorem ipsum");
}
Enter fullscreen mode Exit fullscreen mode

如你所见,<div>语法糖被编译为React.createElement。这就是为什么我们需要在文件顶部导入 React 。否则,我们将收到无法找到 React 的运行时错误。

import React from 'react'
Enter fullscreen mode Exit fullscreen mode

生产createElement实施
开发createElement实施

但那是直到React v17.0Babel v7.9TypeScript v4.1才出现的,因为在那之后他们决定将 JSX 创建提取到与 React 分离的单独工厂中,并自动导入 🚀 🚀 🚀

生产jsx实施
开发jsx实施

你还在吗?我们继续深入探讨 😀

努力工作的男人

因此,如果一切配置正确,则此示例:

function Component() {
  return <div className="yay">lorem ipsum</div>
}
Enter fullscreen mode Exit fullscreen mode

将被编译成如下内容:

import { jsx } from "react/jsx-runtime";
function Component() {
  return jsx("div", { className: "yay", children: "lorem ipsum" });
}
Enter fullscreen mode Exit fullscreen mode

在未来的稳定版本中(已经发布),React 将支持一组用于实例化 JSX 元素的新函数,作为旧版通用 React.createElement 函数的替代。这将允许在未来更好地优化它们。

我们看到<div>语法糖在构建时被编译了jsx(...),但是在运行时这个调用会发生什么呢?好吧,让我们用 console.log 记录这个调用。

当 React 调用Component

function Component() {
  return jsx("div", { className: "yay", children: "lorem ipsum" });
}
Enter fullscreen mode Exit fullscreen mode

它将返回:

function Component() {
  return {
    $$typeof: Symbol('react.element'),
    props: { className: 'yay', children: 'lorem ipsum' },
    type: "div",
  };
}
Enter fullscreen mode Exit fullscreen mode

实际上有一个开放的RFC,似乎 React 团队最终会决定将 JSX 直接编译为返回的这个对象。

例如,如果我们想要渲染Compnent到 DOM。有了这个调用

ReactDOM.render(<Component />, rootElement);
Enter fullscreen mode Exit fullscreen mode

它将被编译为:

ReactDOM.render(
  { $$typeof: Symbol('react.element'), type: Component },
  rootElement
);
Enter fullscreen mode Exit fullscreen mode

最终,我们的组件只是一些函数,它们返回一些代表我们想要渲染的内容的对象。因此,当我们创建组件时,返回的内容并不是最终渲染的内容。ReactDOM 使用一些 props 调用我们的函数组件,查看返回的对象定义,并决定在屏幕上渲染什么以及如何渲染。那么 JSX 呢?JSX 只是一些我们熟悉的语法,因为我们了解 HTML。

但是现在我们知道,直到我们的组件进入 ReactDOM 之前,它会经过一些步骤和转换。

此外,JSX 不再是 React 独有的东西,它已经在很多项目中使用,比如 vue、stenciljs、dom-chef 等等……

感觉没人在读这些文章😀
如果你在这里,感谢读者!♥️


封面照片由Alexandre DebièveUnsplash上拍摄

文章来源:https://dev.to/iamandrewluca/jsx-at-lowest-level-371b
PREV
我转向了 Web 开发
NEXT
👀 检测您的网站何时对用户可见 funtabify v1.0