JSX 虽然看起来像 HTML,但本质上会被编译成 React.createElement 调用。因此它遵循 JavaScript 的表达规则,一个表达式必须有且仅有一个返回值。这就决定了 JSX 必须有一个最外层的包裹元素,也就是根元素。
根元素的要求
// ❌ 错误:JSX 不能返回多个并列的兄弟元素
function Component() {
return (
<h1>标题</h1>
<p>内容</p>
);
}
// ✅ 正确:用 <div> 包裹成一个根元素
function Component() {
return (
<div>
<h1>标题</h1>
<p>内容</p>
</div>
);
}
早期开发中,大家经常用 <div> 作为根元素,但这样会在 DOM 中引入多余的无意义节点。对于布局敏感的场景(如 Flexbox / Grid 布局),多余的 <div> 会破坏样式。
Fragment:无 DOM 节点的包裹元素
React 提供了 Fragment(片段)来解决这个问题。它可以充当根元素,但不会在真实 DOM 中生成任何标签。
import { Fragment } from 'react';
function Component() {
return (
<Fragment>
<h1>标题</h1>
<p>内容</p>
</Fragment>
);
}
更常见的写法是使用短语法 <>...</>,效果完全一致,且无需额外导入:
function Component() {
return (
<>
<h1>标题</h1>
<p>内容</p>
</>
);
}
短语法简洁,但在需要添加 key 属性时,必须使用显式的 <Fragment>。例如在列表渲染时:
function List({ items }) {
return (
<dl>
{items.map(item => (
<Fragment key={item.id}>
<dt>{item.term}</dt>
<dd>{item.description}</dd>
</Fragment>
))}
</dl>
);
}
这里每个 dt 和 dd 需要成组,但不想额外套一层 <div>,用 Fragment 加 key 就是最佳选择。
JSX 中的注释写法
在 JSX 中不能直接使用 HTML 注释 <!-- 注释内容 -->,它会被当成普通文本内容输出到页面上。正确的做法是使用 JavaScript 注释,并包裹在花括号 {} 内:
function Component() {
return (
<div>
{/* 这是一个 JSX 注释,不会渲染到 DOM */}
<h1>Hello</h1>
{
// 单行注释也可以,但通常用多行写法更安全
}
</div>
);
}
注意:
- 注释必须在
{}内部,//或/ /均可。 - 多行注释
{/ /}是最常见的用法,因为它能安全跨行,且不影响格式化。 - 在
{}内写注释时,注意不要放在 JSX 属性的赋值表达式中,否则可能报语法错误。
// ❌ 属性值内不能这样写注释
<input value={/* 初始值 */ name} />
// ✅ 可以换行后注释
<input
value={name} // 当前用户名称
/>
掌握 Fragment 和 JSX 注释的细节,能让你的组件结构更干净、代码更易于维护,同时避免不必要的 DOM 层级污染。