Skip to main content

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