网站首页 > 基础教程 正文
在 React 渲染组件时,每个组件只能返回一个根节点(root element)。传统上,如果我们需要渲染多条并列的元素,通常会使用一个多余的 <div> 或者其他容器标签将它们包裹起来。但是,这样会在最终的 HTML 中多生成一个无意义的节点,可能会影响样式、布局,甚至带来不必要的性能开销。
为了消除这种“无意义的包裹元素”,React 引入了 <Fragment> 组件。它 在渲染时不会生成额外的 DOM 节点,仅仅是一个“虚拟”容器,帮助我们在 JSX 中满足“只能返回一个根节点”的规则。它的本质只是 React 的一个内置组件,本身并不在 DOM 中出现。
Fragment 的用法
最直接的写法是直接从 React 库中导入 Fragment,然后在 JSX 中如下使用:
import React, { Fragment } from 'react';
function MyComponent() {
return (
<Fragment>
<h1>标题</h1>
<p>文字描述</p>
</Fragment>
);
}
上面代码,组件返回了一个 <Fragment>,内部包含多个并列元素;渲染到网页时并不会多出一个父级标签,而是直接渲染 <h1>、<p>、<ul> 三个元素。
如果你不想写 import { Fragment } from 'react',也可以直接使用全称:
import React from 'react';
function MyComponent() {
return (
<React.Fragment>
<h1>标题</h1>
<p>这是一段描述文字。</p>
</React.Fragment>
);
}
export default MyComponent;
两者效果是完全一样的。
简写方式
从 React 16.2 开始,官方支持了 <Fragment> 的简写语法——空标签 <>...</>,使用起来更简洁:
function MyComponent() {
return (
<>
<h1>标题</h1>
<p>这是一段描述文字。</p>
<ul>
<li>列表项 1</li>
<li>列表项 2</li>
</ul>
</>
);
}
两者(<Fragment>...</Fragment> 与 <>...</>)在渲染结果上没有区别。它们都不会在 DOM 中生成额外的节点。
注意: 空标签的简写语法 不能 使用 key 或其他属性,比如 <> 无法写成 < key="..." >。如果需要给 Fragment 本身指定 key,就必须使用完整写法 <Fragment key={...}>...</Fragment>。
比如这种情况
import React from 'react';
function TodoList({ todos }) {
return (
<ul>
{todos.map((todo) => (
<Fragment key={todo.id}>
<li>{todo.text}</li>
<li>状态:{todo.completed ? '已完成' : '未完成'}</li>
</Fragment>
))}
</ul>
);
}
如果使用简写空标签 <>...</> 则无法指定 key,会导致警告或无法正常做列表 Diff。因此在需要绑定 key 的场景下一定要使用 <Fragment key={...}>...</Fragment>。
常见使用场景
组件返回多个并列节点
如果父级容器已足够,只想返回多条标签而不加冗余容器:
function ArticleSummary({ title, excerpt }) {
return (
<>
<h2>{title}</h2>
<p>{excerpt}</p>
</>
);
}
表格中渲染多行
<table> 要求直接返回 <tr>,不能多包一层 <div>。<Fragment> 可把两行或多行当作一组处理:
import React, { Fragment } from 'react';
function DataTable({ list }) {
return (
<table>
<tbody>
{list.map(item => (
<Fragment key={item.id}>
<tr>
<td>{item.name}</td>
<td>{item.value}</td>
</tr>
<tr>
<td colSpan="2">详情:{item.detail}</td>
</tr>
</Fragment>
))}
</tbody>
</table>
);
}
条件渲染多节点
当一个条件下需要返回多条并列节点,用 Fragment 代替冗余父元素,更清爽:
function UserStatus({ user }) {
return (
<>
<h3>{user.name}</h3>
{user.online ? <p>在线</p> : <p>离线</p>}
</>
);
}
与其他方式对比
多包一个 <div>
虽然能满足语法,但会产生额外节点,可能破坏 CSS 布局(如 Flex、Grid)或增深 DOM 层级。
返回数组
可以直接写数组返回多个元素,但每个元素都要写 key,可读性差:
function Example() {
return [
<h1 key="title">标题</h1>,
<p key="content">内容</p>,
];
}
相比之下,Fragment 更简洁可读,且不用给内部每个元素都写 key(只需给 Fragment 本身写一次)。
以上就是本文的全部内容了,如果本文对你有帮助的话请转发给你的工友~
想了解 React 的更多玩法,欢迎关注《React 中文教程》
猜你喜欢
- 2025-06-10 “吃”走肌少症("吃"走肌少症怎么办)
- 2025-06-10 使用python3爬取网页,aria2下载最新电影,Jellyfin播放电影
- 2025-06-10 「数据分析」2种常见的反爬虫策略,信息验证和动态反爬虫
- 2025-06-10 庆祝中华人民共和国成立70周年联欢活动在京举行(八)
- 2025-06-10 Python学不会来打我(48)正则表达式爬取网易云音乐
- 2025-06-10 防脱洗发水是个伪命题?8979条数据告诉你答案
- 2025-06-10 豆包用的大型与DeepSeek大型实际生成代码哪家强
- 2024-07-26 2021年最全的Python爬虫学习笔记(下)
- 2024-07-26 HTML DOM Table 对象(html中的对象)
- 2024-07-26 你可能不重视的一些好用技能(这些技能希望你永远用不到,但一定要知道!)
- 最近发表
- 标签列表
-
- jsp (69)
- gitpush (78)
- gitreset (66)
- python字典 (67)
- dockercp (63)
- gitclone命令 (63)
- dockersave (62)
- linux命令大全 (65)
- pythonif (86)
- location.href (69)
- dockerexec (65)
- tail-f (79)
- queryselectorall (63)
- location.search (79)
- bootstrap教程 (74)
- deletesql (62)
- linuxgzip (68)
- 字符串连接 (73)
- html标签 (69)
- c++初始化列表 (64)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)