Rendering a group of components together without a parent element is possible with React fragments. Learn more in this post.
React is a JavaScript library used for creating interactive web frontend applications. We combine components into an app by passing data from parent components to child components.
One thing we often have to do in our React apps is to render a group of components together. To do this without rendering them in a parent element, we can use fragments. In this article, we will look at how to use React fragments.
Fragments are needed when we want to render a group of elements without a parent element or component. To use it, we either use the Fragment
component or <></>
for short.
For instance, instead of writing:
export default function App() {
return (
<div className="App">
<h1>Hello</h1>
<h2>World</h2>
</div>
);
}
which renders the h1
and h2
elements inside a div, we write:
export default function App() {
return (
<>
<h1>Hello</h1>
<h2>World</h2>
</>
);
}
to just render the h1
and h2
elements without the div around them.
Fragments are needed because components need to be rendered in a container.
React fragments are handy for dividing things like table cells into their own components. For instance, we write:
const Cells = () => {
return (
<>
<td>Hello</td>
<td>World</td>
</>
);
};
export default function App() {
return (
<table>
<tr>
<Cells />
</tr>
</table>
);
}
We can put the td
elements in the Cells
component by themselves because the fragment acts as the parent for the td
elements. Therefore, we can just put
the Cells
component as the child of the tr
element.
We can also use fragments as prop values. For instance, we write:
const AlertDialog = ({ children, buttons, open }) => {
return (
<dialog open={open}>
{children}
{buttons}
</dialog>
);
};
const OKButton = () => <button>OK</button>;
const CancelButton = () => <button>Cancel</button>;
const CloseDialog = ({ open }) => {
const buttons = (
<>
<OKButton />
<CancelButton />
</>
);
return (
<AlertDialog buttons={buttons} open={open}>
Are you sure you want to leave this page?
</AlertDialog>
);
};
export default function App() {
return <CloseDialog open />;
}
to create the AlertDialog
component that has the children
prop. This means we can pass a button in between the AlertDialog
tags.
It also takes the buttons
prop which renders after the children
. We pass in the buttons
fragment as the value of the buttons
prop.
And it renders the OKButton
and CancelButton
after “Are you sure you want to leave this page?” as a result. Therefore, fragments can be passed in as prop values.
Fragments can be used to render list items. To do this, instead of using the <></>
shorthand, we use the Fragment
component.
This is needed because we need to pass the key
prop to Fragment
, which we can only do with the Fragment
component.
For instance, we write:
import { Fragment } from "react";
const posts = [
{
id: 1,
title: "The Ultimate Guide to Preparing for a Standardized Test",
body:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vulputate purus sapien. "
},
{
id: 2,
title: "5 Effective Study Strategies for Any Test",
body:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vulputate purus sapien. "
},
{
id: 3,
title: "How to Combat Test Anxiety and Improve Your Scores",
body:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vulputate purus sapien. "
},
{
id: 4,
title: "The Pros and Cons of Online vs. In-Person Testing",
body:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vulputate purus sapien. "
},
{
id: 5,
title: "The Importance of a Good Night's Sleep Before a Test",
body:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vulputate purus sapien. "
},
{
id: 6,
title: "The Importance of a Good Night's Sleep Before a Test",
body:
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vulputate purus sapien. "
}
];
const PostTitle = ({ title }) => <h1>{title}</h1>;
const PostBody = ({ body }) => <div>{body}</div>;
export default function App() {
return posts.map((post) => (
<Fragment key={post.id}>
<PostTitle title={post.title} />
<PostBody body={post.body} />
</Fragment>
));
}
We render the posts
array into HTML by calling map
with a callback that returns a fragment for each post
entry. We pass in a unique ID value for each
entry as the value of the key
prop so React can identify and keep track of each component.
And we render anything we want inside Fragment
as usual. As a result, only the h1
s and div
s are rendered since we put PostTitle
and PostBody
in Fragment
.
One catch we have to be aware of is that switching between <><Child /></>
and [<Child />]
does not trigger re-rendering of the component that renders them. This
also applies if we switch between <><Child /></>
and <Child />
.
We can put text together with components in fragments. For instance, we write:
const DatePicker = ({ date }) => {
return <input type="date" value={date} />;
};
const DateRangePicker = ({ start, end }) => {
return (
<>
From
<DatePicker date={start} />
to
<DatePicker date={end} />
</>
);
};
export default function App() {
return <DateRangePicker start="2023-01-01" end="2023-01-31" />;
}
to create the DateRangePicker
component by putting text with the DatePicker
component in the same fragment.
As a result, we see one date input after “From” and another one after “to.”
One thing we often have to do in our React apps is to render a group of components together. To do this without rendering them in a parent element, we can use fragments.
We can use them to render lists and they can be used as props and child components.
John Au-Yeung is a frontend developer with 6+ years of experience. He is an avid blogger (visit his site at https://thewebdev.info/) and the author of Vue.js 3 By Example.