You can run into a scenario where you want something to return multiple elements. However, in React your components have to return a single element.
Traditionally, if you wanted to return a list of elements, this would force you to wrap the list in an extra DOM element.
Fragments give us an element we can use to wrap lists, and they don't output extra content in the DOM. They look like this.
render() {
return (
<React.Fragment>
<ChildA />
<ChildB />
<ChildC />
</React.Fragment>
);
}
The <React.Fragment>
object lets you meet the requirement that a single object is returned, yet when rendering the DOM results in only rendering the list of children it contains.
Why Do We Need Fragments?
Here's a scenario where Fragments really solve a problem. Let's say we are rendering a table. The <table>
block contains rows and columns.
In React we might try to generate a row in the table, but this would result in invalid HTML since a <div>
element cannot wrap those table elements.
render() {
return (
<div>
<td>Column 1</td>
<td>Column 2</td>
</div>
);
}
The invalid HTML would look something like this:
<table>
<tr>
<div>
<td>Column 1</td>
<td>Column 2</td>
</div>
</tr>
</table>
Instead of wrapping those columns in a <div>
we can use Fragments!
render() {
return (
<React.Fragment>
<td>Column 1</td>
<td>Column 2</td>
</React.Fragment>
);
}
This would output clean and valid HTML.
<table>
<tr>
<td>Column 1</td>
<td>Column 2</td>
</tr>
</table>
Mapping with Fragments
Another use case for wrapping lists of components is inside of a loop. For example, when mapping through a list of rows you can wrap the output in a Fragment instead of an unnecessary DOM element.
{rows.map(row => (
<React.Fragment key={row.id}>
<dt>{row.name}</dt>
<dd>{row.score}</dd>
</React.Fragment>
)
)}
Short Hand Fragments
Fragments get even better. As long as you don't need to add attributes, like a key or other props, you can use the shorthand syntax.
This makes it even faster to adjust your code such that you can return lists of elements without having to add additional DOM boilerplate code.
render() {
return (
<>
<td>Column 1</td>
<td>Column 2</td>
</>
);
}
Fragments are a great solution that allow you to return lists of components when needed, without adding boilerplate to the DOM. Clean up your DOM with React Fragments!