JSX:JavaScript扩展和使用示例

作者: IT Sectr 发布日期: 2026-07-03 阅读时间: 10 分钟

JSX — 是一种类似XML的JavaScript语法扩展,由React团队开发,用于声明式地描述用户界面。与模板引擎不同,JSX被编译为普通的JavaScript函数调用,在标记内部提供语言的完整能力。根据React, 2024,JSX在所有现代React框架和库中都得到支持。

要点

  • JSX — 是React.createElement之上的语法糖,允许在JavaScript中编写类似HTML的标记。
  • 表达式在JSX中通过花括号嵌入——可以使用任何JS表达式。
  • 属性在JSX中以camelCase编写(className,onClick,tabIndex),而不是kebab-case。
  • 转译JSX到JS由Babel、TypeScript或esbuild在浏览器执行之前完成。
  • XSS保护是内置的——React在渲染前对所有值进行转义,防止注入攻击。

什么是JSX?

JSX(JavaScript XML)——JavaScript的一种语法扩展,于2013年首次在React中引入。它允许开发人员以声明式的方式描述用户界面的结构,将标记和逻辑结合在一个文件中。

在JSX出现之前,开发人员使用文本模板(Mustache、Handlebars)或通过document.createElement手动创建DOM元素。两种方法都有缺点:文本模板不进行类型检查,手动创建DOM繁琐且容易出错。

React选择了不同的道路——将标记直接嵌入到代码中。这一决定在社区中引起了争论,但随着时间的推移成为了标准。如今,JSX不仅用于React,还用于SolidJS、Preact、Qwik,甚至通过插件用于Vue。

JSX基础语法

JSX元素看起来像HTML标签,但直接嵌入在JavaScript中。每个元素被转译为对React.createElement的调用,带有三个参数:元素类型、props对象和子元素。一个根元素——强制规则:JSX表达式必须返回一个父元素或片段。

js
import React from 'react';

// 基本JSX - 单个根元素
const element = (
  <div className="app">
    <h1>Hello, World!</h1>
    <p>Welcome to React</p>
  </div>
);

用于分组的片段

当不需要额外的DOM节点时,使用React.Fragment或简短语法<></>。片段不创建真实的DOM元素,只对子节点进行分组。这在表格和列表中特别有用,因为额外的包装会破坏HTML结构。

js
function Columns() {
  return (
    <>
      <td>First</td>
      <td>Second</td>
    </>
  );
}

JSX中的表达式和变量

任何JavaScript表达式都可以通过花括号嵌入到JSX中{ }。内部可以使用变量、函数调用、三元运算符和数组方法。条件渲染通过三元运算符或逻辑AND完成。

js
function Greeting({ name, isLoggedIn }) {
  const items = ['Red', 'Green', 'Blue'];

  return (
    <div>
      {/* Expression with variable */}
      <h1>Hello, {name}</h1>

      {/* Conditional rendering */}
      {isLoggedIn ?
        <p>Welcome back!</p :
        <button>Login</button>
      }

      {/* Render array */}
      <ul>
        {items.map(item =>
          <li key={item}>{item}</li>
        )}
      </ul>
    </div>
  );
}

关键限制——花括号内只能使用表达式,不能使用语句。不能使用if/else、for、switch——只能使用三元运算符、逻辑运算符和数组方法。允许函数调用,包括箭头函数。

JSX与HTML的区别

JSX在视觉上类似于HTML,但有着根本的区别。属性以camelCase编写——className代替class,onClick代替onclick,tabIndex代替tabindex。这是因为JSX被转译为JavaScript,而在JavaScript中属性名不允许使用连字符。

HTMLJSX原因
class="wrapper"className="wrapper"class——JS中的保留字
onclick="handle()"onClick={handle}JS属性的camelCase
style="color: red"style={{ color: 'red' }}样式对象代替字符串
<input disabled><input disabled={true}>布尔属性的显式指定

另一个重要区别——自闭合标签。在HTML中,某些标签(br、hr、input)可以不闭合。在JSX中,所有自闭合标签必须有闭合斜杠:<br /><input />。SVG属性名也转换为camelCase:strokeWidth、fillOpacity。

JSX如何转译为JavaScript

浏览器不直接理解JSX。在执行之前,JSX代码通过转译器——Babel、TypeScript或esbuild。每个JSX元素被转换为对createElement或jsx/runtime的调用。

通过Babel进行转换

js
// 原始JSX
const element = <h1 className="title">Hello</h1>;

// 转译后
const element = React.createElement(
  'h1',
  { className: 'title' },
  'Hello'
);

从React 17开始,出现了一种新的JSX转换,不需要导入React。自动导入jsx-runtime允许在不需要import React from 'react'的情况下编写组件。Babel和TypeScript通过设置{"runtime": "automatic"}来支持这种转换。

React之外的JSX:Solid、Preact、Vue

虽然JSX与React相关联,但其他框架也使用它。SolidJS使用JSX并编译为真实的DOM节点,无需Virtual DOM。Preact——React的轻量级替代品,完全支持JSX。Vue通过@vue/babel-plugin-jsx支持JSX,尽管其主要模板是template。

关键区别——表达式的语义。在React中,JSX表达式在每次渲染时执行。在SolidJS中,JSX被编译一次,更新通过信号跟踪。这影响性能:SolidJS不需要Virtual DOM和协调,因此JSX渲染更快。

在TypeScript中,JSX在语言级别得到支持。扩展名为.tsx的文件自动处理JSX语法。props的类型化——TypeScript + JSX的主要优势之一:IDE提示预期的属性、回调类型和props的必需性。

使用JSX的最佳实践

编写易于阅读和维护的JSX代码。将复杂表达式提取到单独的变量或函数中——这提高了可读性,并允许独立于标记测试逻辑。使用片段代替不必要的div包装。

缩进规则——为嵌套元素保持缩进。每个嵌套级别——一个缩进级别。闭合标签应与开放标签对齐。对于长属性,使用换行。

避免在props中使用内联箭头函数,如果它们在每次渲染时被创建。在这种情况下,将回调包装在useCallback中或将函数放在组件外部。将复杂组件拆分为更小的组件——每个组件应负责接口的一个逻辑单元。

常见问题

可以在没有React的情况下使用JSX吗?

可以,通过Babel插件@babel/plugin-transform-react-jsx可以为任何库配置JSX。SolidJS、Preact、Nerv和其他框架使用JSX配合自己的运行时。为了完全独立,可以将pragma设置为自己的函数。

为什么在JSX中不能使用class代替className?

class是JavaScript中的保留字。JSX被转译为createElement,其中第二个参数是props对象。class属性与ES6类语法冲突,因此React选择了className。

如何在JSX中添加多个类?

使用模板字符串或classnames库:className={`“btn ${isActive ? 'active' : ''}”`}。对于复杂逻辑,请连接npm包clsxclassnames,它们接受对象和数组。

JSX支持条件构造吗?

JSX只支持表达式,不支持语句。对于条件,使用三元运算符、逻辑AND(&&)或逻辑OR(||)。对于复杂逻辑,将条件提取到单独的变量或函数中。

为什么在JSX中列表需要key?

key属性帮助React在重新渲染时识别列表元素。没有key时,React在更改时重绘整个列表。使用唯一key时,React重用DOM节点并重新排序元素,而不是重新创建它们。

总结

  • JSX——用于声明性描述UI的类似XML的JavaScript扩展,是文本模板的替代方案。
  • 花括号允许嵌入任何JS表达式——变量、函数、三元运算符。
  • 属性在JSX中以camelCase编写,样式作为对象传递,布尔属性显式指定。
  • 转译JSX到createElement由Babel或TypeScript自动完成。
  • 一个根元素或片段对于每个JSX表达式是强制性的。
  • React之外的JSX——SolidJS、Preact、Vue和Qwik也通过自己的运行时支持JSX。
  • TypeScript与.tsx扩展名一起提供props和JSX属性的完整类型化。

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读