Fragments are a way to group multiple elements without creating an additional DOM node. They allow a component to return multiple child elements without wrapping them in extra div elements.
✅ Advantages of fragments:
❌ Problems with div wrappers:
Key rule: Use fragments instead of div wrappers when you need to group elements without affecting the DOM structure! 🎯
Imagine you’re wrapping a gift. Instead of putting the gift in a box and then putting that box in another box, fragments are like a transparent bag that holds things together without adding extra packaging! 🎁
Fragments allow grouping elements without creating an additional DOM node:
// Fragment syntax
function MyComponent() {
return (
<>
<h1>Header</h1>
<p>Paragraph</p>
</>
);
}
// Alternative syntax
function MyComponent() {
return (
<React.Fragment>
<h1>Header</h1>
<p>Paragraph</p>
</React.Fragment>
);
}
Fragments solve the problem of extra nesting:
// ❌ Problem with div wrapper
function BadComponent() {
return (
<div>
<td>Cell 1</td>
<td>Cell 2</td>
</div>
);
}
// This breaks HTML table structure!
// ✅ Solution with fragment
function GoodComponent() {
return (
<>
<td>Cell 1</td>
<td>Cell 2</td>
</>
);
}
// This works correctly in tables!
Fragments don’t add extra elements to the DOM:
// Without fragments - extra div elements
function WithoutFragments() {
return (
<div>
<div>
<h1>Header 1</h1>
<p>Text 1</p>
</div>
<div>
<h2>Header 2</h2>
<p>Text 2</p>
</div>
</div>
);
}
// DOM: div > div > (h1 + p), div > (h2 + p)
// Extra div elements!
// With fragments - clean structure
function WithFragments() {
return (
<div>
<>
<h1>Header 1</h1>
<p>Text 1</p>
</>
<>
<h2>Header 2</h2>
<p>Text 2</p>
</>
</div>
);
}
// DOM: div > h1 + p + h2 + p
// Clean structure without extra wrappers!
Fewer DOM elements = better performance:
// Performance comparison
function PerformanceComparison() {
const items = Array.from({ length: 1000 }, (_, i) => i);
return (
<div>
{/* With div wrappers - more DOM elements */}
{items.map(item => (
<div key={`bad-${item}`}>
<span>Item {item}</span>
<span>ID: {item}</span>
</div>
))}
{/* With fragments - fewer DOM elements */}
{items.map(item => (
<React.Fragment key={`good-${item}`}>
<span>Item {item}</span>
<span>ID: {item}</span>
</React.Fragment>
))}
</div>
);
}
Fragments help maintain HTML semantics:
// In tables
function TableRows() {
return (
<table>
<tbody>
<tr>
<td>Row 1, Column 1</td>
<td>Row 1, Column 2</td>
</tr>
{/* ❌ Can't use div inside tbody */}
{/* <div>
<td>Row 2, Column 1</td>
<td>Row 2, Column 2</td>
</div> */}
{/* ✅ Fragments work correctly */}
<>
<td>Row 2, Column 1</td>
<td>Row 2, Column 2</td>
</>
</tbody>
</table>
);
}
// In lists
function ListItems() {
return (
<ul>
<li>Item 1</li>
{/* ❌ Can't use div inside ul */}
{/* <div>
<li>Item 2</li>
<li>Item 3</li>
</div> */}
{/* ✅ Fragments work correctly */}
<>
<li>Item 2</li>
<li>Item 3</li>
</>
</ul>
);
}
// ✅ When component should return multiple elements
function UserProfile() {
return (
<>
<h1>User Profile</h1>
<p>Name: John Doe</p>
<p>Email: john@example.com</p>
</>
);
}
// ✅ Conditional rendering without extra wrappers
function ConditionalContent({ showDetails }) {
return (
<div>
<h2>Header</h2>
{showDetails && (
<>
<p>Details 1</p>
<p>Details 2</p>
</>
)}
</div>
);
}
// ✅ Grouping elements in lists
function ItemGroup({ items }) {
return (
<div>
{items.map(item => (
<React.Fragment key={item.id}>
<h3>{item.title}</h3>
<p>{item.description}</p>
<hr />
</React.Fragment>
))}
</div>
);
}
// Short syntax (preferred)
function ShortSyntax() {
return (
<>
<h1>Header</h1>
<p>Paragraph</p>
</>
);
}
// Full syntax (when attributes are needed)
function FullSyntax() {
return (
<React.Fragment key="unique-key">
<h1>Header</h1>
<p>Paragraph</p>
</React.Fragment>
);
}
// ❌ Incorrect mixing
function BadMixing() {
return (
<>
<React.Fragment>
<h1>Header</h1>
<p>Paragraph</p>
</React.Fragment>
</>
);
}
// ✅ Proper usage
function GoodUsage() {
return (
<>
<h1>Header</h1>
<p>Paragraph</p>
</>
);
}
// ❌ Can't use attributes with <>
function BadAttributes() {
return (
// ❌ Error: <> cannot have attributes
// < key="something">
// <h1>Header</h1>
// </>
);
}
// ✅ Using attributes with React.Fragment
function GoodAttributes() {
return (
<React.Fragment key="unique-key">
<h1>Header</h1>
<p>Paragraph</p>
</React.Fragment>
);
}
// ❌ Extra div wrapper
function BadWrapper() {
return (
<div>
<h1>Header</h1>
<p>Paragraph</p>
</div>
);
}
// ✅ Fragment without extra wrapper
function GoodFragment() {
return (
<>
<h1>Header</h1>
<p>Paragraph</p>
</>
);
}
Fragments are like invisible packaging that holds elements together without adding anything extra to the DOM! 📦
When to use fragments:
When div wrappers are acceptable:
Practical rule: By default, use fragments, switch to div only when styling or semantics are needed.
Fragments are a simple but powerful React feature that helps write cleaner and more efficient code! 💪
Want more useful React articles? Subscribe to EasyAdvice, bookmark the site and level up every day! 🚀