Back to React
React
medium
mid

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.

4 min read·~5 min to think through

Fragments solve a specific JSX limitation: a component can return only one element, but sometimes you need siblings without an extra DOM wrapper.

Shorthand

tsx
function Buttons() {
  return (
    <>
      <button>Save</button>
      <button>Cancel</button>
    </>
  );
}

No wrapping <div> in the DOM — just two sibling <button>s.

Explicit form

tsx
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.

tsx
// Without fragment — div breaks grid layout
function Row() {
  return (
    <div>
      <span>a</span>
      <span>b</span>
    </div>
  );
}

2. Tables require strict parent/child structure.

tsx
// 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.

tsx
{users.map(u => (
  <Fragment key={u.id}>
    <dt>{u.name}</dt>
    <dd>{u.email}</dd>
  </Fragment>
))}

Limitations

  • The shorthand <>...</> cannot take a key or 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 children only, 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.

Senior engineer discussion

Senior framing: Fragments exist because JSX's 'one element per return' constraint sometimes fights semantic HTML or CSS. They're a small ergonomic feature that prevents a whole class of div-soup mistakes.

Related questions