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.
Tips
- 01Use the <></> short syntax by default for cleaner code, but switch to React.Fragment when you need the key prop.
Warnings
- 01Fragments don't support className, id, or other attributes — use a div if you need to style the wrapper.
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> </>
FAQ
Use React.Fragment when you need to pass a key prop, such as when rendering a list of fragments. The short syntax <></> doesn't accept any props, so explicit React.Fragment is the only option in those cases.
No, Fragments don't support any DOM attributes like className, id, or style. If you need to style the wrapper element, use a div or another semantic HTML element instead.
Map over your data and return React.Fragment with a key prop for each item: items.map(item => <React.Fragment key={item.id}>...</React.Fragment>). This avoids wrapper divs while satisfying React's key requirement for lists.
No, Fragments are invisible in the DOM — they leave no trace in the rendered HTML. Your flex or grid container will see the Fragment's children as direct children, which is exactly why Fragments are useful for avoiding layout-breaking wrapper divs.
Fragments themselves don't affect render order, so if children appear out of order the issue is elsewhere — typically conditional rendering logic or an unsorted data source. Check the order of expressions inside your Fragment and the data being mapped.