A typical React component is expected to return multiple JSX elements. Fragments in React allow you to return multiple child elements without populating unnecessary nodes to the DOM. This is in line with React's component architecture, and it also enhances performance in complex and deeper apps.
This guide explores an easy approach to render many HTML elements in React.js through React fragments.
Before React 16.2, you could render only a single DOM node inside the render method. Now you can render multiple DOM nodes. In order to do this, wrap it inside a parent div
which essentially makes it a single DOM node with multiple elements inside it. Fragments in React do not deviate much from their literal meaning. When rendering DOM elements in a component, a fragment allows you to group together your DOM elements inside a pseudo wrapper. This wrapper, the fragment itself, is not regarded as a DOM node.
Consider the following code snippet :
1class Countries extends React.Component {
2 render() {
3 return (
4 <li>Canada</li>
5 <li>Australia</li>
6 <li>Norway</li>
7 <li>Mexico</li>
8 )
9 }
10}
If you run this code in React, you'll get an error: Syntax error: Adjacent JSX elements must be wrapped in an enclosing tag
. React sees your render method trying to output multiple DOM nodes and bars you from doing so by throwing this error.
Modify the above code like this and you'll notice that the error goes away.
1class Countries extends React.Component {
2 render() {
3 return (
4 <div className="country-names">
5 <li>Canada</li>
6 <li>Australia</li>
7 <li>Norway</li>
8 <li>Mexico</li>
9 </div>
10 )
11 }
12}
The way out is making use of a wrapper div
or span
element that acts as the enclosing tag. Essentially, React sees the render method outputting a single DOM node with multiple child elements inside.
Make sure you have Nodejs and npm installed in your machine (at least version 8 or higher), along with a code editor and a web browser (preferably Chrome or Firefox).
Create a new project using create-react-app:
1npx create-react-app react-read-more
Remove the logo, App.css
, and all their imports from App.js
. Clean out the starter template inside the App component. Your App.js
should look like
this:
1import React from 'react';
2import './App.css';
3
4function App() {
5 return(
6 <div className="App">
7 </div>
8 )
9}
10
11export default App;
Note: Sometimes removing App.css might land you an error. In such cases, instead of deleting the App.css, keep it empty, or if you have already deleted it, create a blank CSS file under the same name in the root directory.
Inside the root directory, run :
1npm start
This will spin up a local development server (usually on port 3000) and you can see all your changes live in the browser.
Wrap your JSX in an enclosing <React.Fragment>
tag
.
1import React from 'react';
2import './App.css';
3
4function App() {
5 return (
6 <React.Fragment>
7 <li>ReactJS</li>
8 <li>AngularJS</li>
9 <li>VueJS</li>
10 <li>Bootstrap</li>
11 </React.Fragment>
12
13 );
14}
15
16export default App;
You can avoid the React.Fragment
keyword and simply contain your fragment's content inside a pair of <> </>
. This is a shorthand syntax for fragments, as shown below
.
1import React from 'react';
2import './App.css';
3
4function App() {
5 return (
6 <>
7 <li>ReactJS</li>
8 <li>AngularJS</li>
9 <li>VueJS</li>
10 <li>Bootstrap</li>
11 </>
12
13 );
14}
15
16export default App;
You can render as many elements inside a fragment as child nodes that follow their regular tree structure, as the fragment itself is not a DOM node.
1import React from 'react';
2import './App.css';
3
4function App() {
5 return (
6 <>
7 <div> This is a div
8 <h2> This is a div sub heading </h2>
9 </div>
10 <li>This is list item 1</li>
11 <li>This is list item 2</li>
12 <li>This is list item 3</li>
13 <div>This is another div
14 <p>some text inside div</p>
15 </div>
16 </>
17
18
19 );
20}
21
22export default App;
For instance, in the above example, your fragment has five parent nodes: first a <div>
, followed by three <li>
s, and then another <div>
. Inside the <div>
, you have child elements <h2>
and <p>
. Thus your DOM model is still maintained as a hierarchical tree.
You can embed your UI components as fragment components in a single component. Let's take a use case where you want to render a list of continents, countries, and cities. The ideal approach would be to divide these lists into separate components and then render them in their parent component. Inside the src
folder, create a new folder, components
, and create the following components:
This component renders a list of continents inside a fragment.
1import React from 'react';
2
3const Continents=()=>{
4 return(
5 <React.Fragment>
6 <li>Asia</li>
7 <li>Austrailia</li>
8 <li>Antarctica</li>
9 </React.Fragment>
10 )
11}
12
13export default Continents;
This component renders a list of countries inside a fragment.
1import React from 'react';
2
3const Countries=()=>{
4 return(
5 <React.Fragment>
6 <li>India</li>
7 <li>China</li>
8 <li>Germany</li>
9 </React.Fragment>
10 )
11}
12
13export default Countries;
This component renders a *ist of cities inside a fragment.
1import React from 'react';
2
3const Cities=()=>{
4 return(
5 <React.Fragment>
6 <li>Mumbai</li>
7 <li>Bengaluru</li>
8 <li>Kolkata</li>
9 </React.Fragment>
10 )
11}
12
13export default Cities;
Finally, import all the components and render them inside App.js
.
1import React from 'react';
2import './App.css';
3import Continents from './components/Continents';
4import Countries from './components/Countries';
5import Cities from './components/Cities';
6
7function App() {
8 return (
9 <>
10 <Continents></Continents>
11 <Countries></Countries>
12 <Cities></Cities>
13 </>
14 );
15}
16
17export default App;
Instead of creating separate components, you can also put it all together in one component.
1import React from 'react';
2import './App.css';
3
4const Continents=()=>{
5 return(
6 <React.Fragment>
7 <li>Asia</li>
8 <li>Austrailia</li>
9 <li>Antarctica</li>
10 </React.Fragment>
11 )
12}
13
14const Countries=()=>{
15 return(
16 <React.Fragment>
17 <li>India</li>
18 <li>China</li>
19 <li>Germany</li>
20 </React.Fragment>
21 )
22}
23
24const Cities=()=>{
25 return(
26 <React.Fragment>
27 <li>Mumbai</li>
28 <li>Bengaluru</li>
29 <li>Kolkata</li>
30 </React.Fragment>
31 )
32}
33
34function App() {
35 return (
36 <>
37 <Continents></Continents>
38 <Countries></Countries>
39 <Cities></Cities>
40 </>
41 );
42}
43
44export default App;
Now you have used essentially a single component to render many HTML fragments. Thus, fragments also help you organize your code better, make it more modular without the need for an extra parent node every time you're grouping some DOM elements together.
Let's look at why fragments were introduced and their obvious advantages .
Using fragments is a tad bit faster, which becomes evident for component trees extending deep in your frontend's architecture.
Imagine one less parent wrapper for every fragment in a large app that used hundreds of components and even more embedded inside them. It makes a considerable performance difference for such an application, rendering it light-weight and resulting in smoother user experience.
Modern CSS structures for positioning and containing elements like flexbox
and grid
rely on their special parent-child relationship. Adding unnecessary additional divs
can often give unwanted results or make it difficult to design what you intend to. Even those CSS frameworks that depend heavily on flexbox layouts like Bootstrap can offer some discrepancies while utilizing those mechanisms. Fragments ensure that your design layouts lay intact, just as they're supposed to be.
Breaking down code into modular fragments is more logical. It keeps your HTML/JSX concise, clean, and less messy. This also makes debugging HTML and CSS easier on both the editor and the inspector .
As a developer, you can benefit from the urge to learn new features and adopt good coding practices. React 16.2 offers a number of exciting updates that can make your development process faster and less cumbersome. Through this guide, you learned what fragments are and how to use them to render multiple HTML fragments inside a single component.