Technology · React
React Fragment and Keys
Master React.Fragment, short syntax, and when keys are necessary.
TL;DR
- 01Use Fragment to group elements without adding a wrapper div.
- 02Use the <></> short syntax for cleaner code.
- 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.