Fragments
React requires every component to return a single root element. The
obvious solution — wrapping everything in a <div> — works, but it
pollutes the DOM with nodes that exist solely to satisfy React's rule.
Those extra nodes can break CSS layouts, invalidate HTML semantics, and
add pointless weight to the page. Fragments solve this cleanly:
they let you group elements without adding any node to the DOM.
The Problem: Wrapper Divs
Before fragments existed, developers wrapped siblings in a <div>.
Consider a component that renders two table cells:
// ❌ Extra <div> breaks table structure
function TableCells({ item }) {
return (
<div>
<td>{item.name}</td>
<td>{item.price}</td>
</div>
)
}
// Usage inside a table row:
<tr>
<TableCells item={product} />
</tr>This produces invalid HTML — a <div> cannot be a direct child of
<tr>. Browsers try to recover by moving the <div> outside the
table, breaking the layout entirely. Fragments solve this:
// ✅ Fragment — zero DOM nodes added
function TableCells({ item }) {
return (
<>
<td>{item.name}</td>
<td>{item.price}</td>
</>
)
}
// The rendered HTML is now valid:
// <tr>
// <td>Apple</td>
// <td>$1.99</td>
// </tr>Two Syntaxes
There are two ways to write a Fragment. They are functionally identical except for one important difference covered in the next section:
import React from 'react'
// Syntax 1: Shorthand (most common)
function ShorthandFragment() {
return (
<>
<h1>Title</h1>
<p>Paragraph</p>
</>
)
}
// Syntax 2: Explicit React.Fragment
function ExplicitFragment() {
return (
<React.Fragment>
<h1>Title</h1>
<p>Paragraph</p>
</React.Fragment>
)
}When You Need the Explicit Syntax: the key Prop
The shorthand <></> syntax does not support attributes. The one
case where you need the explicit <React.Fragment> form is when
rendering a list of fragments that each require a key prop:
// ❌ Shorthand cannot accept key
function DefinitionList({ terms }) {
return (
<dl>
{terms.map((term) => (
<> {/* Can't put key here */}
<dt>{term.word}</dt>
<dd>{term.definition}</dd>
</>
))}
</dl>
)
}
// ✅ Explicit Fragment supports the key prop
import { Fragment } from 'react'
function DefinitionList({ terms }) {
return (
<dl>
{terms.map((term) => (
<Fragment key={term.id}>
<dt>{term.word}</dt>
<dd>{term.definition}</dd>
</Fragment>
))}
</dl>
)
}Practical Use Cases
Fragments are useful in any situation where extra DOM nodes would be problematic or redundant:
// 1. Table rows — <tr> can only contain <td>/<th>
function DataRow({ row }) {
return (
<>
<td>{row.date}</td>
<td>{row.amount}</td>
<td>{row.status}</td>
</>
)
}
// 2. List items returned from a helper
function ContactInfo({ contact }) {
return (
<>
<li>{contact.email}</li>
<li>{contact.phone}</li>
</>
)
}
// 3. Conditional blocks without extra wrappers
function AlertArea({ alerts }) {
return (
<div className="alerts">
{alerts.map((alert) => (
<Fragment key={alert.id}>
<AlertIcon type={alert.type} />
<AlertMessage text={alert.message} />
<Divider />
</Fragment>
))}
</div>
)
}
// 4. Multiple elements returned from a helper function
function renderBreadcrumbs(path) {
return path.map((segment, i) => (
<Fragment key={segment.href}>
{i > 0 && <span> / </span>}
<a href={segment.href}>{segment.label}</a>
</Fragment>
))
}The DOM Output
To see the difference fragments make, compare the DOM output of a Fragment vs a wrapper div for a simple two-element component:
// With a wrapper div:
function WithDiv() {
return (
<div>
<h2>Section</h2>
<p>Content</p>
</div>
)
}
// With a Fragment:
function WithFragment() {
return (
<>
<h2>Section</h2>
<p>Content</p>
</>
)
}DOM output of WithDiv:
<div> <h2>Section</h2> <p>Content</p> </div>
DOM output of WithFragment:
<h2>Section</h2> <p>Content</p>
Performance: Why Wrapper Divs Are Not Free
Every DOM node has a cost. The browser must:
Allocate memory for the node
Recalculate layout (reflow) when nodes change
Apply CSS rules that might match the new element
Include it in accessibility trees that assistive technologies traverse
In an application that renders thousands of list items or table rows, unnecessary wrapper elements add up. Fragments keep the DOM lean. They also prevent CSS issues — flexbox and grid layouts, for example, are sensitive to unexpected wrapper elements that break the direct parent-child relationship required for flex/grid items to work.
Summary
Fragments let you group multiple elements without adding a DOM node
Shorthand
<></>is the common case;<Fragment key={...}>is needed for keyed listsCritical for valid HTML inside tables (
<tr>/<td>), lists (<ul>/<li>), and other elements with strict child rulesKeeps the DOM clean — avoids extra divs that break CSS flex/grid layouts
Import
Fragmentfrom'react'when you need the explicit form:import { Fragment } from 'react'