React Fragments

React Fragments let you group multiple elements without adding an extra DOM node. They solve the requirement that every JSX expression must have a single root element — without wrapping everything in an unnecessary <div> that pollutes the HTML structure.

The Problem Without Fragments

React requires every component to return a single root element. When two elements need to sit side by side, developers used to wrap them in a <div>.

// Without Fragments — forced wrapper div
function UserInfo() {
  return (
    <div>   {/* This div adds nothing but exists to satisfy React */}
      <h2>Alice Johnson</h2>
      <p>alice@example.com</p>
    </div>
  );
}

This works, but it adds a meaningless <div> to the DOM. In large apps with many components, these wrapper divs accumulate into what developers call "div soup" — deeply nested HTML that makes CSS layout and browser devtools harder to work with.

The Fragment Solution

import { Fragment } from "react";

function UserInfo() {
  return (
    <Fragment>
      <h2>Alice Johnson</h2>
      <p>alice@example.com</p>
    </Fragment>
  );
}

The <Fragment> wrapper disappears from the actual DOM. The browser only sees <h2> and <p> — no wrapper at all.

Short Syntax: Empty Tags

React provides a shorthand for Fragment using empty angle brackets <></>. This is the most common syntax in modern React code.

function UserInfo() {
  return (
    <>
      <h2>Alice Johnson</h2>
      <p>alice@example.com</p>
    </>
  );
}

Comparing the DOM Output

With a div wrapper

/* React output */
<div>     <!-- unnecessary wrapper -->
  <h2>Alice Johnson</h2>
  <p>alice@example.com</p>
</div>

With a Fragment

/* React output */
<h2>Alice Johnson</h2>
<p>alice@example.com</p>
/* No wrapper! Clean output. */

When Fragments Really Matter: Table Rows

Tables have strict rules about which elements can be children of <tr>, <tbody>, and <table>. Adding a <div> wrapper breaks the table structure entirely. Fragments are the correct solution here.

// WRONG — div inside table row breaks HTML validity
function TableColumns({ product }) {
  return (
    <div>
      <td>{product.name}</td>
      <td>{product.price}</td>
      <td>{product.stock}</td>
    </div>
  );
}

// CORRECT — Fragment keeps table structure valid
function TableColumns({ product }) {
  return (
    <>
      <td>{product.name}</td>
      <td>{product.price}</td>
      <td>{product.stock}</td>
    </>
  );
}

// Parent table
function ProductTable({ products }) {
  return (
    <table>
      <tbody>
        {products.map((product) => (
          <tr key={product.id}>
            <TableColumns product={product} />
          </tr>
        ))}
      </tbody>
    </table>
  );
}

Fragments in Lists: Using the key Prop

The short syntax <></> does not support any props — including the key prop. When rendering lists of fragments, use the explicit <Fragment> syntax with key.

import { Fragment } from "react";

const people = [
  { id: 1, name: "Alice", role: "Admin" },
  { id: 2, name: "Bob", role: "Editor" },
];

function PeopleList() {
  return (
    <dl>
      {people.map((person) => (
        <Fragment key={person.id}> {/* key only works on Fragment, not <> */}
          <dt>{person.name}</dt>
          <dd>{person.role}</dd>
        </Fragment>
      ))}
    </dl>
  );
}

Diagram: dl/dt/dd output without a Fragment wrapper

/* Without Fragment, forced to use div — breaks dl semantics */
<dl>
  <div>         ← invalid inside dl!
    <dt>Alice</dt>
    <dd>Admin</dd>
  </div>
</dl>

/* With Fragment — clean, semantically correct */
<dl>
  <dt>Alice</dt>
  <dd>Admin</dd>
  <dt>Bob</dt>
  <dd>Editor</dd>
</dl>

Fragments with Flexbox and Grid Layouts

Adding a <div> wrapper inside a flex or grid container creates an extra element that disrupts column or row alignment. Fragments let child elements participate directly in the parent layout.

// Parent is a flex container
<div style={{ display: "flex" }}>
  <SidebarSection />   {/* Returns <><p>...</p><p>...</p></> */}
  <MainSection />      {/* Returns <><article>...</article></> */}
</div>

If SidebarSection used a <div>, the flex layout would treat the whole <div> as one flex item. With a Fragment, each paragraph inside SidebarSection becomes a direct flex item.

Fragment vs div: When to Use Each

Use <></> Fragment when:
  • You need to group elements with no layout purpose
  • Table structure requires it (<tr>, <td>, <dt>, <dd>)
  • Adding a div would break CSS layout (flex/grid)
  • You want clean, minimal DOM output

Use <div> when:
  • The wrapper itself needs CSS styles
  • The wrapper needs a className or event handler
  • The group needs an ID or data attribute
  • You need the wrapper in the DOM for layout reasons

Summary

React Fragments group multiple JSX elements under a single return without adding any DOM node. The short syntax <></> works everywhere a Fragment is needed except when you need to pass a key prop — use <Fragment key={id}> for keyed list rendering. Fragments are essential for valid HTML in tables, definition lists, and other elements with strict child requirements. They also prevent layout disruption in flex and grid containers where an unwanted wrapper element changes the structure. Use Fragments by default when grouping elements; use a <div> only when the wrapper itself needs to carry styles or attributes.

Leave a Comment

Your email address will not be published. Required fields are marked *