What are React Fragments and why would you use them?
Fragments let a component return multiple elements without an extra wrapper DOM node. `<>...</>` (shorthand) or `<Fragment>...</Fragment>` (explicit, accepts a `key` prop). Use them to avoid unnecessary divs that break CSS Grid/Flexbox layouts, to keep tables valid, and to return sibling elements from map callbacks.
Fragments solve a specific JSX limitation: a component can return only one element, but sometimes you need siblings without an extra DOM wrapper.
Shorthand
function Buttons() {
return (
<>
<button>Save</button>
<button>Cancel</button>
</>
);
}No wrapping <div> in the DOM — just two sibling <button>s.
Explicit form
import { Fragment } from 'react';
<Fragment>
<li>A</li>
<li>B</li>
</Fragment>Required when you need a key prop (the shorthand doesn't accept attributes).
Why fragments matter
1. CSS layouts break with extra wrappers.
// Without fragment — div breaks grid layout
function Row() {
return (
<div>
<span>a</span>
<span>b</span>
</div>
);
}2. Tables require strict parent/child structure.
// Invalid HTML
<tr>
<div>
<td>a</td>
<td>b</td>
</div>
</tr>
// Valid with Fragment
<tr>
<Fragment>
<td>a</td>
<td>b</td>
</Fragment>
</tr>3. Mapping multiple sibling elements per item.
{users.map(u => (
<Fragment key={u.id}>
<dt>{u.name}</dt>
<dd>{u.email}</dd>
</Fragment>
))}Limitations
- The shorthand
<>...</>cannot take akeyor any prop. Use the long form when needed. - Fragments don't render anything in the DOM — they're purely a JSX construct.
- TypeScript: fragments accept
childrenonly, no other props.
Avoiding the temptation to overuse divs
Every unnecessary <div>:
- Adds DOM weight.
- Breaks layout queries (
:nth-child, grid auto-placement). - Makes accessibility tree noisier.
If a component returns siblings, reach for a fragment — not a wrapper div with no semantic role.
When you DO want a wrapper
If you need to attach a className, onClick, or a ref, you need a real element. Use a <div>, <span>, or a semantic tag. Fragments give you 'no wrapper' — they're not a place to hang attributes.
Follow-up questions
- •Why can't the shorthand fragment take a key prop?
- •When would you wrap in a div instead of a fragment?
- •Does Fragment have a performance cost?
Common mistakes
- •Wrapping in div when a Fragment would do — bloats DOM and breaks layouts.
- •Trying to use shorthand as a keyable list item — needs explicit Fragment.
- •Expecting Fragment to render a wrapper element — it doesn't.
Performance considerations
- •Fragments have negligible cost. They're a marker in React's virtual tree; no DOM node is created or compared. Replacing a wrapper div with a Fragment is a tiny but real DOM size win across a large app.
Edge cases
- •Fragments inside table rows are valid; div is not.
- •CSS :first-child / :nth-child counts real DOM elements, not fragments.
- •React DevTools shows fragments as a separate tree node, but the DOM has nothing.
Real-world examples
- •Table row generators, description lists, layouts using CSS Grid where children must be direct siblings, definition lists rendering multiple dt/dd per data item.