React 第二十五节 <Fragment></Fragment> 的用途以及使用注意事项详解

文章如果错误偏差,烦请及时批评指正

一、为什么要使用 <Fragment>

因为在 React 中,组件必须 返回单个根元素。当我们尝试直接返回相邻的 JSX 元素时:

javascript 复制代码
    function BrokenComponent() {
        return (
            <h1>标题</h1>
            <p>正文内容</p>
        );
    }
    //  报错:Adjacent JSX elements must be wrapped in an enclosing tag

传统解决方案是使用
包裹,但这会带来 三大问题

1、破坏布局结构:多余的 DOM 节点可能干扰 CSS 布局(如 Flex/Grid)

2、性能损耗:增加无意义的 DOM 层级

3、语义污染:无关的
影响 HTML 语义化

二、基础用法:两种写法全解析

  1. 显式写法(推荐场景:需要 key 属性时)
    当我们遍历数组时,需要添加 key 属性时,我们需要显式的使用
javascript 复制代码
import React, { Fragment } from 'react';
function ListItems() {
  return (
    <Fragment>
      <li>第一项</li>
      <li>第二项</li>
      <li>第三项</li>
    </Fragment>
  );
}
  1. 简写语法(空标签)
javascript 复制代码
    function ShortSyntax() {
    return (
        <>
        <h2>欢迎界面</h2>
        <button>开始使用</button>
        </>
    );
    }

三、实际开发过程中的应用场景

  1. 列表渲染(必须使用 key)
javascript 复制代码
    function UserList({ users }) {
    return users.map(user => (
        <Fragment key={user.id}>
        <dt>{user.name}</dt>
        <dd>{user.email}</dd>
        </Fragment>
    ));
    }
    //  正确:Fragment 支持 key 属性
    //  错误:空标签语法 <></> 不能添加属性
  1. 条件渲染
javascript 复制代码
    function AuthButton({ isLoggedIn }) {
    return (
        <Fragment>
        {isLoggedIn ? (
            <button>退出登录</button>
        ) : (
            <Fragment>
            <button>登录</button>
            <button>注册</button>
            </Fragment>
        )}
        </Fragment>
    );
    }
  1. 表格结构
    需要注意添加 标签的位置
javascript 复制代码
    function TableData() {
    return (
        <table>
            <tbody>
                <tr>
                <Fragment>
                    <td>单元格1</td>
                    <td>单元格2</td>
                </Fragment>
                </tr>
            </tbody>
        </table>
        );
    }
    // 注意:直接包裹 <tr> 会破坏表格结构
  1. 组合组件
javascript 复制代码
    function Layout() {
    return (
        <>
        <Header />
        <MainContent />
        <Footer />
        </>
    );
    }
  1. 高阶组件(HOC)
javascript 复制代码
    const withLogger = (WrappedComponent) => {
        return (props) => (
            <Fragment>
                <ConsoleLogger />
                <WrappedComponent {...props} />
            </Fragment>
        );
    };
  1. 渲染数组
javascript 复制代码
    function ArrayRender() {
    return (
        <>
        {['A', 'B', 'C'].map((item) => (
            <Fragment key={item}>
            <span>{item}</span>
            <br />
            </Fragment>
        ))}
        </>
    );
    }

四、深度原理剖析

源码实现(简化版):

javascript 复制代码
    const Fragment = Symbol.for('react.fragment');

    function createFragment(children) {
    return {
        $$typeof: Symbol.for('react.element'),
        type: Fragment,
        props: { children },
        key: null
    };
    }

React 在调和(Reconciliation)阶段会:

识别 Fragment 类型

直接平铺其子节点

不创建真实 DOM 节点

五、开发者常遇到问题

1、样式丢失陷阱

javascript 复制代码
// 错误示例:
    <div className="parent">
        <>
            <Child style={{ margin: 10 }} />
        </>
    </div>
// 正确:直接在父级设置样式容器 无脑简写导致 key 缺失
javascript 复制代码
// 错误示例:
    {items.map(item => (
    <>  // 错误 缺少 key
        <span>{item.name}</span>
        <span>{item.value}</span>
    </>
    ))}

2、多层 Fragment 嵌套

javascript 复制代码
// 不良实践:
<>
  <>
    <ComponentA />
    <ComponentB />
  </>
  <ComponentC />
</>
// 建议:单层 Fragment 保持结构清晰

3、与第三方库的冲突

javascript 复制代码
    // 某些动画库(如 Framer Motion)需要真实 DOM:
    <motion.div>
        <Fragment> //错误 动画失效
            {/* content */}
        </Fragment>
    </motion.div>

4、开发工具调试困惑

Fragment 在 React DevTools 中显示为 ,可通过设置显示名称优化:

javascript 复制代码
    const MyFragment = ({ children }) => <Fragment>{children}</Fragment>;
    MyFragment.displayName = 'MyFragment'; // 调试更友好

七、注意事项

1、优先使用空标签语法:<>...</> 简洁直观

2、需要 key 时切回显式 Fragment:列表项必须添加

3、避免深度嵌套:超过 3 层应考虑组件拆分,考虑组件的单一性易维护性

4、组件中需要结合 TypeScript 增加类型检查,避免使用人员传入不符合类型的数据

javascript 复制代码
const FragmentWrapper: React.FC<{ children: React.ReactNode }> = 
  ({ children }) => <>{children}</>;

5、性能敏感场景实测:大数据列表优先选择 Fragment

6、最后:当你在纠结是否使用 Fragment 时,先问自己两个问题:

这个容器是否需要任何样式或交互?

添加 DOM 节点是否会影响父级布局?

满足这两个条件,可以放心使用

相关推荐
崔庆才丨静觅7 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60618 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了8 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅8 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅8 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅9 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment9 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅9 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊9 小时前
jwt介绍
前端
爱敲代码的小鱼9 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax