Skip to content
React rc jsx 4 min read

Fragments

A React component must return a single root element, but real UIs are full of sibling elements that don’t naturally share a parent. Fragments solve this by letting you group children without wrapping them in an extra DOM node. The result is cleaner markup, fewer layout headaches, and HTML that behaves the way the spec intends.

Why a component returns one root

JSX compiles to function calls, and a return statement can only return one value. When you write JSX, the outermost element becomes that single returned value. Returning two adjacent elements is therefore a syntax error:

function Profile() {
  // This will NOT compile
  return (
    <h1>Ada Lovelace</h1>
    <p>The first programmer.</p>
  );
}

The classic workaround is to wrap everything in a <div>. That works, but it pollutes the DOM with containers that exist only to satisfy React. Over many components this becomes “wrapper-div soup” that complicates CSS and breaks layout primitives like Flexbox, Grid, and <table>.

Using a Fragment

A Fragment is an invisible wrapper. It satisfies the single-root rule while rendering nothing to the DOM. Use it via React.Fragment or the <>...</> shorthand:

import { Fragment } from "react";

function Profile() {
  return (
    <Fragment>
      <h1>Ada Lovelace</h1>
      <p>The first programmer.</p>
    </Fragment>
  );
}

The shorthand syntax is more common because it is concise and reads as “just a group”:

function Profile() {
  return (
    <>
      <h1>Ada Lovelace</h1>
      <p>The first programmer.</p>
    </>
  );
}

Both versions produce identical DOM output — no wrapper element at all:

Output:

<h1>Ada Lovelace</h1>
<p>The first programmer.</p>

Where Fragments shine: valid HTML structures

Some HTML elements have strict parent-child rules. A <tr> may only contain <td>/<th>, and a <td> may contain anything — but a stray <div> between a <table> and its rows is invalid. Fragments let a component return multiple cells without breaking the structure:

function Columns({ row }) {
  return (
    <>
      <td>{row.name}</td>
      <td>{row.role}</td>
    </>
  );
}

function Table({ people }) {
  return (
    <table>
      <tbody>
        {people.map((p) => (
          <tr key={p.id}>
            <Columns row={p} />
          </tr>
        ))}
      </tbody>
    </table>
  );
}

Here <Columns> injects two <td> siblings directly into the <tr>, with no illegal wrapper in between.

Keyed Fragments in lists

When you render a list and each item needs to produce multiple elements, you need a key on the outer group. The <> shorthand cannot take attributes, so you must use the explicit <React.Fragment> form with a key:

function Glossary({ items }) {
  return (
    <dl>
      {items.map((item) => (
        // The shorthand <> cannot accept a key here
        <Fragment key={item.term}>
          <dt>{item.term}</dt>
          <dd>{item.definition}</dd>
        </Fragment>
      ))}
    </dl>
  );
}

This keeps <dt> and <dd> as direct children of <dl> (which is required for valid description lists) while still giving React the stable key it needs to track each pair.

Tip: key is the only prop a Fragment accepts. Passing any other attribute (like className or event handlers) does nothing — Fragments render no element to attach them to.

Shorthand vs. explicit form

Feature<>...</> shorthand<React.Fragment>...</React.Fragment>
Renders a DOM nodeNoNo
Accepts keyNoYes
Requires an importNoYes (Fragment)
Best forGeneral groupingKeyed list items

Avoiding wrapper-div soup

Reach for a Fragment whenever a <div> would exist purely to group siblings and carries no styling or semantic meaning. Compare the DOM produced by a wrapper-heavy layout versus a Fragment-based one:

// Adds an extra layout node that can disrupt the parent's Grid/Flex flow
function WithDiv() {
  return (
    <div>
      <Label />
      <Input />
    </div>
  );
}

// Children become direct participants of the parent layout
function WithFragment() {
  return (
    <>
      <Label />
      <Input />
    </>
  );
}

If the parent is a CSS Grid expecting <Label> and <Input> as direct grid items, the wrapper <div> collapses them into one cell, whereas the Fragment preserves the intended layout.

Best Practices

  • Prefer the <>...</> shorthand for everyday grouping — it is the cleanest way to satisfy the single-root rule.
  • Switch to <Fragment key={...}> whenever a mapped item returns multiple sibling elements that need a key.
  • Use Fragments to keep table, list, and <select> markup valid instead of inserting illegal wrapper elements.
  • Keep a real <div> (or semantic element) only when it carries styling, semantics, or an event handler — not as a pure grouping crutch.
  • Remember that Fragments accept no props except key; reach for a real element when you need className, ref, or handlers.
  • Watch your imports: the shorthand needs none, but React.Fragment/Fragment must be imported to use a key.
Last updated June 14, 2026
Was this helpful?