<>...</>
Group sibling elements without adding a wrapper node to the DOM.
<>
<OneChild />
<AnotherChild />
</>- Added in React 16.2.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$childrenoptional | ReactNode | The elements to group. The shorthand accepts no attributes at all — for key or ref you must write <Fragment> explicitly. |
Return value
ReactNodeA single React node wrapping the children, which renders no DOM element of its own.
Errors
Writing any attribute on <> is a syntax error at compile time; the shorthand takes no props.
Changelog
- PHP 16.2.0Fragment and the <>...</> shorthand were introduced; before this a component had to return a single DOM element or an array.
A component must return one node. <>...</> satisfies that without rendering anything: the children land in the parent's DOM as direct siblings.
When to reach for it
- Returning several elements from a component, instead of a wrapper
divthat exists only to satisfy the compiler. - Markup where a wrapper would be invalid:
<td>cells inside a<tr>,<dt>/<dd>pairs in a<dl>,<option>groups. - Flex and grid layouts, where an extra div would become an unwanted grid item.
When you cannot use it
The shorthand takes no attributes. Inside a map(), where each iteration produces several siblings, you need a key — so import Fragment and write <Fragment key={id}>. That is the one case where the long form is mandatory.
What trips people up
The shorthand is JSX syntax, not a value: you cannot pass <> as a variable or use it in a non-JSX position.
Going from <><Child /></> to a bare <Child /> preserves state, but only one level deep — a double-nested fragment collapsing to a single child resets it.
Example
When to use it
- Returning a heading and a paragraph from one component without a wrapper
- Emitting several <td> cells from a shared row-fragment component
- Producing dt/dd pairs from a map with a keyed Fragment
- Keeping a flex container's direct children intact when a component is inserted
Frequently asked questions
Why does React say 'JSX expressions must have one parent element'?
Because a component returned two or more sibling elements at the top level. Wrap them in <>...</> — that satisfies the single-root rule without adding anything to the DOM.
How do I add a key to a fragment?
You cannot with the <> shorthand; import Fragment from react and write <Fragment key={id}>...</Fragment>. This is the only situation where the long form is required rather than a style choice.
Does a fragment appear in the DOM?
No — it renders nothing itself, and its children become direct children of whatever contains the fragment. That is exactly why it is safe inside tables, definition lists and flex containers.
More examples
Markup where a wrapper would be invalid
A <div> around the two cells would be invalid inside a <tr> and browsers would hoist it out of the table, wrecking the layout. The fragment lets MoneyCells contribute cells directly. The key here sits on the <tr> created by the map, so the shorthand is fine inside the component itself.
function MoneyCells({ amount, currency }) {
return (
<>
<td>{currency}</td>
<td>{amount.toFixed(2)}</td>
</>
);
}
const LINES = [
{ id: 1, label: "Hosting", amount: 12.5, currency: "EUR" },
{ id: 2, label: "Domain", amount: 9, currency: "EUR" }
];
export default function Invoice() {
return (
<table>
<tbody>
{LINES.map((line) => (
<tr key={line.id}>
<td>{line.label}</td>
<MoneyCells amount={line.amount} currency={line.currency} />
</tr>
))}
</tbody>
</table>
);
}Fragment as a value, and conditional groups
Two things worth noting. A conditional branch can render a fragment, so && can produce several elements at once without a wrapper. And Fragment — unlike the <>...</> syntax — is an ordinary value that can be assigned to a variable and used as a component, which is how libraries make a wrapper element optional.
import { Fragment } from "react";
function Details({ expanded, item }) {
return (
<li>
{item.title}
{expanded && (
<>
<p>{item.summary}</p>
<p>Updated {item.updated}</p>
</>
)}
</li>
);
}
const ITEM = { title: "Release notes", summary: "Two fixes.", updated: "2026-01-04" };
export default function Feed() {
// Fragment is a real component, so it can be stored in a variable.
const Wrapper = Fragment;
return (
<Wrapper>
<ul>
<Details expanded={false} item={ITEM} />
<Details expanded={true} item={ITEM} />
</ul>
</Wrapper>
);
}
Discussion