Skip to content

ReactJS - JSX

React 使用 JSX(JavaScript XML)作为 JavaScript 的语法扩展,它允许你在 JavaScript 代码中编写类似 HTML 的结构。虽然你可以在没有 JSX 的情况下使用 React,但由于以下几个优点,使用 JSX 是一个普遍且推荐的做法:

  • JSX 更具可读性和表达性,特别是对于熟悉 HTML 的开发者而言,因为它直观地表示了 UI 结构。
  • 许多构建工具会优化 JSX 的编译,这可能带来性能上的提升。
  • JSX 有助于更早地捕获错误,如果语法不正确,通常在编译阶段就能发现。

JSX 元素看起来与 HTML 标签非常相似。以下是一个在函数式组件中的基本示例:

import React from 'react';
function App() {
return (
<div>
Hello World!!!
</div>
);
}
export default App;

虽然 JSX 类似于 HTML,但有一些关键差异和规则需要记住。

一个 React 组件的 render 方法(针对类组件)或 return 语句(针对函数式组件)必须返回单个根元素。如果你想返回多个元素,可以将它们包裹在一个父标签中,比如 <div>,或者使用 React.Fragment(或其简写 <></>)来避免在 DOM 中添加额外的节点。

import React from 'react';
function App() {
return (
<React.Fragment>
<h1>Header</h1>
<h2>Content</h2>
<p>This is the content!!!</p>
</React.Fragment>
// 或者使用简写语法:
// <>
// <h1>Header</h1>
// <h2>Content</h2>
// <p>This is the content!!!</p>
// <>
);
}
export default App;

输出将显示一个标题、一个副标题和一个段落,如果使用 Fragment,它们在 DOM 中会作为同级元素渲染;如果使用 div 包裹,它们会嵌套在 div 中。

JSX 对大多数 HTML 属性名使用 camelCase(驼峰命名法)。例如,class 变为 className,for 变为 htmlFor。这是因为 JSX 更接近 JavaScript 而不是 HTML,而 class 和 for 是 JavaScript 中的保留关键字。你也可以使用标准的 HTML 属性和自定义数据属性(以 data- 开头)。

import React from 'react';
function App() {
return (
<div>
<h1 className="main-title">Header</h1>
<h2>Content</h2>
<p data-custom-attribute="somevalue">This is the content!!!</p>
<label htmlFor="username">Username:</label>
<input type="text" id="username" />
</div>
);
}
export default App;

你可以通过将任何有效的 JavaScript 表达式包裹在花括号 {} 中来将其嵌入到 JSX 中。例如,要显示算术运算的结果:

import React from 'react';
function App() {
const result = 1 + 1;
return (
<div>
<h1>{result}</h1> {/* 显示 2 */}
<p>User: {'John Doe'.toUpperCase()}</p> {/* 显示 User: JOHN DOE */}
</div>
);
}
export default App;

第一个例子的输出将是一个包含数字 2 的 <h1> 标签。

标准的 if-else 语句不能直接在 JSX 内部使用。但是,你可以使用条件(三元)表达式或逻辑 && 运算符来进行条件渲染。

import React from 'react';
function App() {
const isLoggedIn = true;
let count = 5;
return (
<div>
<h1>{isLoggedIn ? 'Welcome Back!' : 'Please Log In'}</h1>
{count > 0 && <p>You have {count} new messages.</p>}
</div>
);
}
export default App;

在这个例子中,‘Welcome Back!’ 将会被渲染。如果 isLoggedIn 为 false,则会显示 ‘Please Log In’。如果 count 大于 0,则会显示关于新消息的文本。

React 允许使用内联样式。应用内联样式时,你需要将一个 JavaScript 对象传递给 style 属性。属性名称使用 camelCase(例如,fontSize 而不是 font-size)。React 会自动为某些数值型的内联样式属性追加 px。虽然内联样式对于动态样式或简单情况很方便,但在大型应用中,考虑使用 CSS Modules、CSS-in-JS 库(如 Styled Components 或 Emotion)或工具优先的 CSS 框架(如 Tailwind CSS),以实现更好的可维护性和可扩展性。有关更多信息,请参阅 [Link to React Docs on Styling and CSS]。

import React from 'react';
function App() {
const myStyle = {
fontSize: '32px', // 明确设置 px,或者对于某些属性,可以使用数字让 React 推断
color: '#FF0000',
backgroundColor: 'lightyellow' // background-color 的 camelCase 写法
};
return (
<div>
<h1 style={myStyle}>Header with Inline Styles</h1>
</div>
);
}
export default App;

标题文本将以 32px 的字体大小、红色和浅黄色背景渲染。

要在 JSX 中编写注释,你需要将注释内容包裹在花括号 {} 中,然后使用 JavaScript 的注释语法 (/* ... */)。

import React from 'react';
function App() {
return (
<div>
<h1>Header</h1>
{/* 这是 JSX 中的单行注释 */}
{/*
这是 JSX 中的
多行注释
*/}
<p>Some content.</p>
</div>
);
}
export default App;

标准的 HTML 元素使用小写字母编写(例如,<div>,<p>)。React 组件,无论是基于类的还是函数式的,都必须以大写字母开头(例如,<MyComponent />,<UserProfile />)。这种区别对于 JSX 至关重要,以便区分 HTML 标签和 React 组件。

请记住,对于 CSS 类,使用 className 而不是 class;对于 label 元素中的 for 属性,使用 htmlFor。由于 JSX 是 JavaScript,这些是重要的区别。

如 React 官方文档所述:

由于 JSX 是 JavaScript,不建议将诸如 class 和 for 之类的标识符用作 XML 属性名。相反,React DOM 组件需要像 className 和 htmlFor 这样的 DOM 属性名。