在写 React 的同学是不是经常碰到
“JSX 只能有一个根元素!”
“外面还得包一层 div,不然要报错!”
写着写着就变成了:
<div>
<div>
<div>
你好啊,层层叠叠都是 div
</div>
</div>
</div>
纯 div 大楼,冗余到令人发指!
这时候,聪明的前端朋友们会祭出一个神秘武器: <></>
<></> 是什么玩意?
一句话:
<></> 是 React.Fragment 的语法糖!
对,就是个语法糖,和你吃的糖没区别,就是让你写起来更甜一点。
它长得像个空标签,但其实是个隐形容器,包裹一坨兄弟元素,却啥都不渲染。
为什么需要 <></>?
1️⃣ JSX 必须有唯一父元素
React 里每个组件都得返回一个根节点,不然 React 懵了:
// 错的!
return (
<h1>你好</h1>
<p>世界</p>
);
报错:Adjacent JSX elements must be wrapped in an enclosing tag
(翻译一下:兄弟你得找个爹罩着它们!)
所以大家最开始只能硬塞一个 <div>:
return (
<div>
<h1>你好</h1>
<p>世界</p>
</div>
);
2️⃣ “不要为了 div 而 div”
有些时候多一个 <div> 根本没必要,还可能把你的布局搞崩。
比如在 <table> 里:
<table>
<tbody>
<div>
<tr>...</tr> // 报错,table 里不能放 div
</div>
</tbody>
</table>
HTML 语法直接罢工!
✨ <Fragment> 来拯救
这时候 React 发明了 <Fragment>,告诉大家:
“别慌,你可以合法包裹,但啥也不多渲染!”
return (
<React.Fragment>
<h1>你好</h1>
<p>世界</p>
</React.Fragment>
);
运行后 DOM:
html
复制编辑
<h1>你好</h1>
<p>世界</p>
干净!纯粹!没有白白浪费的 div。
🍬 <></> 就是 <React.Fragment> 的小糖果版
手感更丝滑:
jsx
复制编辑
return (
<>
<h1>你好</h1>
<p>世界</p>
</>
);
是不是比写 <React.Fragment> 还省劲?!
功能总结
✅ 保证 JSX 有唯一父元素
✅ 不生成多余的 DOM 标签
✅ 避免“div 大楼”
✅ 性能更好(少一个节点就是少一次回流重绘嘛)
Fragment 的隐藏技能:key
很多同学以为 <></> 万能,但它有个小缺点:不能加属性!
比如你要在列表里循环:
items.map(item => (
<>
<dt>{item.title}</dt>
<dd>{item.desc}</dd>
</>
))
React 会给你黄牌警告:
Each child in a list should have a unique “key” prop.
因为 <> 不能挂 key,怎么办?
把糖衣撕了,老老实实写:
jsx
复制编辑
items.map(item => (
<React.Fragment key={item.id}>
<dt>{item.title}</dt>
<dd>{item.desc}</dd>
</React.Fragment>
))
这样就完美了!
Fragment 既是隐形容器,还能挂 key,React 的 Diff 算法看了也会竖大拇指
🧩 知识彩蛋:浏览器里也有“Fragment”
前端老鸟都知道,原生 JS 里也有个老牌的 DocumentFragment,作用一毛一样:
把一堆 DOM 先挂到“离线容器”里,最后一次性放进页面,避免多次回流重绘,批量挂载性能高。
const frag = document.createDocumentFragment();
items.forEach(item => {
const div = document.createElement('div');
div.textContent = item.title;
frag.appendChild(div);
});
container.appendChild(frag); // 一次挂载,性能好!
是不是跟 React 的 <Fragment> 有异曲同工之妙?
React 只是帮你把这一套打包好了,虚拟 DOM + Fragment + 批量更新,组合技罢了!
写在最后
当你再也不想为了 div 而 div,
当你想让代码更干净、DOM 更优雅、性能更在线,
记住:
<>
我是
你的
Fragment
</>
需要 key?
别犹豫,换上 <React.Fragment key={xxx}>,该稳就稳。
一句话总结
<></>是 React Fragment 的糖衣,吃了甜,写了爽,DOM 没废话,性能还跟着飞!
不想踩坑?项目里一定安排!
有循环就给 Fragment 加 key,别用简写!
不然报错别怪我没提醒你哈~
如果觉得有用,点个赞、点个收藏,别忘了分享给还在堆 div 大楼的同事!
我是小阳,祝你写代码天天甜!🍬