Technology · React

React Fragment and Keys

Master React.Fragment, short syntax, and when keys are necessary.

TL;DR
  1. 01Use Fragment to group elements without adding a wrapper div.
  2. 02Use the <></> short syntax for cleaner code.
  3. 03Fragments cannot have keys unless using React.Fragment explicitly.

Fragment Basics

  • Use React.Fragment to group multiple elements without a wrapper.
    function List() {
      return (
        <React.Fragment>
          <h2>Title</h2>
          <p>Description</p>
        </React.Fragment>
      );
    }
  • Fragments don't create extra DOM nodes.
    // Without Fragment: creates a div
    <div>
      <Header />
      <Content />
      <Footer />
    </div>
    
    // With Fragment: no extra node
    <React.Fragment>
      <Header />
      <Content />
      <Footer />
    </React.Fragment>
  • Return multiple elements from a component.
    function Profile() {
      return (
        <React.Fragment>
          <UserHeader />
          <UserContent />
          <UserFooter />
        </React.Fragment>
      );
    }
  • Use fragments in table rows to avoid invalid HTML.
    function TableRow({ item }) {
      return (
        <React.Fragment>
          <td>{item.name}</td>
          <td>{item.price}</td>
          <td>{item.stock}</td>
        </React.Fragment>
      );
    }
  • Fragments are required when a component must return multiple siblings.
    // JSX requires a single root — Fragment is the clean solution
    function NavItems() {
      return (
        <>
          <li><a href="/home">Home</a></li>
          <li><a href="/about">About</a></li>
          <li><a href="/contact">Contact</a></li>
        </>
      );
    }

Short Syntax

  • Use <></> as shorthand for React.Fragment.
    function List() {
      return (
        <>
          <h2>Title</h2>
          <p>Description</p>
        </>
      );
    }
  • Short syntax is cleaner and more readable.
  • Most projects use <></> instead of React.Fragment.
    // Preferred: short syntax
    <>
      <Component />
    </>
    
    // Also works: full syntax
    <React.Fragment>
      <Component />
    </React.Fragment>
  • Short syntax works in any JSX context.
    function App() {
      return (
        <main>
          <>
            <Sidebar />
            <Content />
          </>
        </main>
      );
    }
  • Use <></> for conditional rendering of multiple elements.
    function Status({ isLoggedIn }) {
      return isLoggedIn ? (
        <>
          <WelcomeMessage />
          <UserMenu />
        </>
      ) : (
        <>
          <LoginPrompt />
          <SignupLink />
        </>
      );
    }

Fragment with Keys

  • Only React.Fragment supports the key prop.
    function List({ items }) {
      return (
        <>
          {items.map(item => (
            <React.Fragment key={item.id}>
              <dt>{item.name}</dt>
              <dd>{item.description}</dd>
            </React.Fragment>
          ))}
        </>
      );
    }
  • Use keys when rendering multiple elements per item.
    // Without key: React can't track which elements belong together
    items.map(item => (
      <React.Fragment key={item.id}>
        <Header title={item.title} />
        <Body content={item.content} />
      </React.Fragment>
    ))
  • Short syntax <></> doesn't support keys.
    // This won't work:
    <>
      {items.map(item => (
        <>
          <p key={item.id}>{item.name}</p>
        </>
      ))}
    </>
  • Place the key on React.Fragment, not on child elements.
    // Wrong: key on child, not on fragment
    {items.map(item => (
      <React.Fragment>
        <p key={item.id}>{item.name}</p>
      </React.Fragment>
    ))}
    
    // Correct: key on the fragment itself
    {items.map(item => (
      <React.Fragment key={item.id}>
        <p>{item.name}</p>
      </React.Fragment>
    ))}
  • Keys must be unique among siblings, not globally unique.
    // These keys are fine — they're in separate lists
    listA.map(item => <React.Fragment key={item.id}>...</React.Fragment>)
    listB.map(item => <React.Fragment key={item.id}>...</React.Fragment>)

Use Cases

  • Return multiple elements from a component.
    function DialogBox() {
      return (
        <>
          <Modal.Header>Confirm Action</Modal.Header>
          <Modal.Body>Are you sure?</Modal.Body>
          <Modal.Footer>
            <button>Cancel</button>
            <button>Confirm</button>
          </Modal.Footer>
        </>
      );
    }
  • Wrap elements for styling without extra divs.
    return (
      <>
        <style>{`
          span { color: red; }
        `}</style>
        <span>Styled text</span>
      </>
    );
  • Group related elements in definition lists.
    function DefinitionList({ terms }) {
      return (
        <dl>
          {terms.map(term => (
            <React.Fragment key={term.id}>
              <dt>{term.word}</dt>
              <dd>{term.definition}</dd>
            </React.Fragment>
          ))}
        </dl>
      );
    }
  • Group table cells when building flexible table row components.
    function ProductRow({ product }) {
      return (
        <tr>
          <React.Fragment>
            <td>{product.name}</td>
            <td>{product.category}</td>
            <td>${product.price}</td>
          </React.Fragment>
        </tr>
      );
    }
  • Avoid invalid HTML nesting by wrapping list items in fragments.
    function NavGroup({ label, links }) {
      return (
        <>
          <li className="group-label">{label}</li>
          {links.map(link => (
            <li key={link.href}>
              <a href={link.href}>{link.text}</a>
            </li>
          ))}
        </>
      );
    }

Common Mistakes

  • Don't use <></> when you need a key on items.
    // Wrong: loses key benefit
    {items.map(item => (
      <>
        <p key={item.id}>{item.name}</p>
      </>
    ))}
    
    // Correct: use React.Fragment with key
    {items.map(item => (
      <React.Fragment key={item.id}>
        <p>{item.name}</p>
      </React.Fragment>
    ))}
  • Don't add classes or other attributes to fragments.
    // Wrong: fragments don't support attributes
    <> className="wrapper">
      <Content />
    </>
    
    // Correct: use a div if you need attributes
    <div className="wrapper">
      <Content />
    </div>
  • Don't forget to import React when using the full syntax.
    // Required for React.Fragment in older setups
    import React from "react";
    
    // Not required for short syntax — handled by JSX transform
    <>...</>
  • Don't use index as key if items can be reordered or removed.
    // Bad: index as key causes issues when list order changes
    {items.map((item, index) => (
      <React.Fragment key={index}>...</React.Fragment>
    ))}
    
    // Good: stable unique ID
    {items.map(item => (
      <React.Fragment key={item.id}>...</React.Fragment>
    ))}
  • Don't nest fragments unnecessarily — keep JSX clean.
    // Unnecessary nesting
    <>
      <>
        <p>Hello</p>
      </>
    </>
    
    // Clean: single fragment
    <>
      <p>Hello</p>
    </>

Tip: Use the <></> short syntax by default for cleaner code, but switch to React.Fragment when you need the key prop.

Warning: Fragments don't support className, id, or other attributes — use a div if you need to style the wrapper.

React Event HandlingReact useContext Hook