React.Fragment and Why Use It
Answer
React Fragment allows you to group multiple children elements without adding extra DOM nodes. It solves the requirement of returning a single element from components.
The Problem
// ❌ Error: Adjacent JSX elements must be wrapped
function App() {
return (
<h1>Title</h1>
<p>Paragraph</p>
);
}
// ❌ Unnecessary div wrapper
function App() {
return (
<div> {/* Extra div in DOM! */}
<h1>Title</h1>
<p>Paragraph</p>
</div>
);
}
The Solution: Fragments
// ✅ Fragment - no extra DOM element
function App() {
return (
<React.Fragment>
<h1>Title</h1>
<p>Paragraph</p>
</React.Fragment>
);
}
// ✅ Short syntax (recommended)
function App() {
return (
<>
<h1>Title</h1>
<p>Paragraph</p>
</>
);
}
DOM Output
<!-- Without Fragment (with div wrapper) -->
<div id="root">
<div>
<h1>Title</h1>
<p>Paragraph</p>
</div>
</div>
<!-- With Fragment -->
<div id="root">
<h1>Title</h1>
<p>Paragraph</p>
</div>
When Fragments Are Essential
Table Rows
// ❌ Wrong: div inside table breaks layout
function TableData() {
return (
<div>
<td>Cell 1</td>
<td>Cell 2</td>
</div>
);
}
// ✅ Correct: Fragment keeps valid HTML structure
function TableData() {
return (
<>
<td>Cell 1</td>
<td>Cell 2</td>
</>
);
}
function Table() {
return (
<table>
<tbody>
<tr>
<TableData />
</tr>
</tbody>
</table>
);
}
Definition Lists
function Glossary({ items }) {
return (
<dl>
{items.map((item) => (
// Fragment groups dt and dd without extra wrapper
<React.Fragment key={item.id}>
<dt>{item.term}</dt>
<dd>{item.description}</dd>
</React.Fragment>
))}
</dl>
);
}
Fragments with Keys
// Short syntax <> doesn't support keys
// Use React.Fragment for lists/maps
// ❌ Can't add key to short syntax
{
items.map((item) => (
<>
{" "}
key={item.id} {/* Won't work! */}
<dt>{item.term}</dt>
<dd>{item.description}</dd>
</>
));
}
// ✅ Use React.Fragment for keys
{
items.map((item) => (
<React.Fragment key={item.id}>
<dt>{item.term}</dt>
<dd>{item.description}</dd>
</React.Fragment>
));
}
Common Use Cases
// 1. Conditional siblings
function Message({ showTitle, showBody }) {
return (
<>
{showTitle && <h1>Welcome</h1>}
{showBody && <p>Hello there!</p>}
</>
);
}
// 2. Returning from array map
function List({ items }) {
return (
<ul>
{items.map((item) => (
<React.Fragment key={item.id}>
<li>{item.name}</li>
{item.hasDivider && <hr />}
</React.Fragment>
))}
</ul>
);
}
// 3. Avoiding styling issues
function FlexItems() {
return (
// Direct children of flex container
<>
<div className="item">1</div>
<div className="item">2</div>
<div className="item">3</div>
</>
);
}
Fragment vs Array
// Less common: Array return
function ArrayReturn() {
return [<h1 key="title">Title</h1>, <p key="para">Paragraph</p>];
}
// Preferred: Fragment (no keys needed for static content)
function FragmentReturn() {
return (
<>
<h1>Title</h1>
<p>Paragraph</p>
</>
);
}
Key Points
- Fragments group elements without adding DOM nodes
- Use
<>...</>short syntax for most cases - Use
<React.Fragment key={...}>when mapping - Essential for valid HTML structure (tables, lists)
- Avoids CSS layout issues from wrapper divs
- Has zero rendering overhead