React 踩坑:忘记使用 React.Fragment 进行返回
·
React 踩坑:忘记使用 React.Fragment 进行返回
—— 从「多余 DOM」到「Syntax Error」的 3 分钟急救
当你在 React 函数组件里写下:
return (
<div>A</div>
<div>B</div> // ❌ JSX 语法错误:Adjacent JSX elements must be wrapped in an enclosing tag
);
或 ESLint 提示:
JSX expressions must have one parent element.
React 告诉你:「必须返回单一根元素」。
本文用「场景 → 修复 → 性能对比」三步法,一次性掌握 React.Fragment 的正确姿势。
一、为什么必须“单根”?
JSX 编译后:
return React.createElement(
'div', null,
React.createElement('div', null, 'A'),
React.createElement('div', null, 'B')
);
createElement 第一参数只能是单个元素或 Fragment,否则语法树无法生成。
二、3 个高频翻车现场 & 修复
1️⃣ 相邻元素直接 return(语法错误)
function Items() {
return (
<li>Apple</li>
<li>Banana</li> // ❌ 相邻元素
);
}
修复 1:显式 <React.Fragment>(兼容所有版本)
import React from 'react';
function Items() {
return (
<React.Fragment>
<li>Apple</li>
<li>Banana</li>
</React.Fragment>
);
}
修复 2:简写 <>(React 16.2+)
function Items() {
return (
<>
<li>Apple</li>
<li>Banana</li>
</>
);
}
2️⃣ 循环返回数组却忘 key
function List({ items }) {
return items.map(item => <li>{item}</li>); // ❌ 缺少 key
}
修复:Fragment + key
return items.map(item => (
<React.Fragment key={item.id}>
<li>{item.name}</li>
</React.Fragment>
));
3️⃣ 条件渲染多根节点
function Status({ isLoading, data }) {
if (isLoading) return <Spinner />;
return <div>{data}</div>; // ✅ 单根,OK
// ❌ 若写成:
// return <Spinner /><div>{data}</div>; // 语法错误
}
修复:Fragment 包裹
return (
<>
{isLoading && <Spinner />}
{!isLoading && <div>{data}</div>}
</>
);
三、性能对比(DevTools Profiler)
| 写法 | DOM 节点 | 重渲染次数 |
|---|---|---|
外层 <div> | +1 包裹节点 | 1 |
<> / <Fragment> | 0 额外节点 | 1(无变化) |
Fragment 不会生成任何真实 DOM,避免「包裹层污染」。
四、特殊场景:需要 key 或 ref
- 列表循环 → 用显式
<React.Fragment key={id}> - 需要 ref → 用
<React.Fragment ref={ref}>(React 18.3+)
return items.map(item => (
<React.Fragment key={item.id} ref={itemRef}>
<li>{item.name}</li>
</React.Fragment>
));
五、一句话总结
「多根必包」——用
<>或<React.Fragment>包裹相邻 JSX,
既不增加 DOM,又让 React 编译顺利通过。
最后问候亲爱的朋友们,并邀请你们阅读我的全新著作
📚 《 React开发实践:掌握Redux与Hooks应用 》

更多推荐
所有评论(0)