Open In App

Why are fragments better than container divs ?

Last Updated : 26 Jun, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

React Fragments are a modern way of adding multiple elements to a React Component without wrapping them in additional DOM nodes. React.js renders the JSX using the return statement. To render a component, we use the render method, which renders a single root node at a time. Whenever we need to render multiple elements, we need to enclose them in a wrapper element. The component will not be rendered on the DOM without a wrapper element.  

We usually create an extra node, i.e. we wrap the content with a ‘div’ tag if we have to return multiple elements from a return statement since only one root node is rendered at a time. Now, an extra div may destructure the DOM in HTML. We can use React Fragment instead of this additional node to eliminate its downsides. 

What makes React Fragments better than div tags as a wrapping element?The problems we might encounter when using a div tag:

  • Increases the size of the DOM: DOM sizes get large when there are too many DOM nodes or HTML tags on your page or when these nodes are nested too deeply. As a result, the user’s browser consumes additional power to process your website, resulting in slow page load time and low page speed scores.
  • Using divs creates extra nodes, resulting in a high memory usage.
  • Oversized DOMs cause memory usage to increase, style processing to lag, and layout reflows to be costly.
  • On older devices, this could clutter your HTML, causing performance issues.
  • Debugging and tracing the origin of the extra nodes become more challenging as the component tree nests deeper.
  • It difficult to maintain the desired layout: Flexbox and Grid have a unique parent-child relationship, and adding divs breaks the markup.

Therefore, React fragments are better than the ‘div’ tags. With React Fragment, you can render multiple elements of a component without adding extra div tags. We can write cleaner, more readable code with React Fragments. It takes up less memory and renders components faster. Each component is rendered as expected. 

Example: Let’s make Color Palette (color shade card) pattern using a flexbox and understand why react fragments are better than ‘div’ tag.

Approach: We will be making a color palette pattern with the help of a flexbox. Basically, It will be a rectangular strip composed of different shades of green. In the following example, we will see how react fragments can help us avoid the downsides of div tags.  

Step 1:  Create a react app 

To create a react app, type the following command into your terminal. We will create a react app named “react-fragments-gfg”.

npx create-react-app react-fragments-gfg

Step 2: The Directory structure currently looks like this:

Default directory Structure 

We will modify the folder and keep the files we need for this example. Now, make sure your file structure looks like this.

DIRECTORY STRUCTURE

Step 3: Write the following code in your app.js file

In the app.js file, we will write code to generate a rectangular strip consisting of boxes of different colors. We will use Flexbox to achieve this. A flexbox arranges items in rows or columns. In this step, we will create a Row component, a Column component, and a Shadecard component. The row is the parent component consisting of a div container that wraps the column and shade card components. When you invoke a component, this.props.children are used to displaying whatever you include between the opening and closing tags. This will display the column and the shade card component. The column component consists of a div container of a class col that wraps the Shadecard component. Every single box represents a Shadecard component. Each box has a distinct color.

Javascript




// App.js file code
import './App.css';
 
// Creating the Row component
const Row = ({ children }) => <div className="row">{children}</div>;
 
// Creating the Column component
const Column = ({ children }) => <div className="col">{children}</div>;
 
// Creating the Shadecard component
const Shadecard = ({ color, shade }) => (
    <div className="card" style={{ backgroundColor: color }}>
        {shade}
    </div>
);
 
const App = () => {
    return (
        <Row>
            <Column>
                <Shadecard color="rgb(224,255,255)" shade="Light Cyan" />
            </Column>
            <Column>
                <Shadecard color="rgb(175,238,238)" shade="pale turquoise" />
            </Column>
            <Column>
                <Shadecard color="rgb(0,255,255)" shade="Aqua" />
            </Column>
            <Column>
                <Shadecard color="rgb(64,224,208)" shade="Turquoise" />
            </Column>
            <Column>
                <Shadecard color="rgb(0,206,209)" shade="Dark Turquoise" />
            </Column>
            <Column>
                <Shadecard color="rgb(0,128,128)" shade="Teal" />
            </Column>
            <Column>
                <Shadecard color="rgb(95,158,160)" shade="Cadet Blue" />
            </Column>
            <Column>
                <Shadecard color="rgb(47,79,79)" shade="Slate Gray" />
            </Column>
        </Row>
    );
}
 
export default App;


Step 4: Modify the index.html file as shown below and remove the unnecessary code already present.

HTML




<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta name="description" content="Web site created using create-react-app" />
    <title>React App</title>
</head>
<body>
    <div id="root"></div>
</body>
</html>


Step 5: Write the following code in your index.js file. The index.js file serves as the main entry point, and inside it the App.js file is rendered at the root ID of the DOM.

App.js

Javascript




import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
 
ReactDOM.render(
  <App /> , document.getElementById('root')
);


Step 6: To style your project, add the following code to the app.css file.

CSS




.row {
    display: flex;
}
 
.col {
    flex: 1;
}
 
.card {
    min-width: 100px;
    min-height: 100px;
    text-align: center;
    font-weight: bold;
    border: 1px solid black;
}


Step 7: Run the following command in your terminal, to run the react application “react-fragments-gfg”. 

npm start 

Output: By default, the React project created will run on port 3000. You can access it at localhost:3000 on your browser. The desired color palette pattern is rendered as shown below.

The desired color palette pattern is rendered

Now, for instance, you might want to decouple the lighter shades from the darker ones and use this as a reusable component.

Step 8: We will refactor the code in our app.js file to separate the lighter shades into a separate component called Lightshades. We will create a separate component “Lightshades” to display the lighter shades, while the Shadecard component contains all of the darker shades. 

Javascript




// Modifying the app.js file
import './App.css';
 
const Row = ({ children }) => <div className="row">{children}</div>;
 
const Column = ({ children }) => <div className="col">{children}</div>;
 
const Shadecard = ({ color, shade }) => (
    <div className="card" style={{ backgroundColor: color }}>
        {shade}
    </div>
);
 
// Separating the light colors into a different component
const Lightshades = () => {
    return (
        <div>
            <Column>
                <Shadecard color="rgb(224,255,255)" shade="Light Cyan" />
            </Column>
            <Column>
                <Shadecard color="rgb(175,238,238)" shade="pale turquoise" />
            </Column>
            <Column>
                <Shadecard color="rgb(0,255,255)" shade="Aqua" />
            </Column>
            <Column>
                <Shadecard color="rgb(64,224,208)" shade="Turquoise" />
            </Column>
        </div>
    );
};
 
const App = () => {
    return (
        <Row>
            <Lightshades />
            <Column>
                <Shadecard color="rgb(0,206,209)" shade="Dark Turquoise" />
            </Column>
            <Column>
                <Shadecard color="rgb(0,128,128)" shade="Teal" />
            </Column>
            <Column>
                <Shadecard color="rgb(95,158,160)" shade="Cadet Blue" />
            </Column>
            <Column>
                <Shadecard color="rgb(47,79,79)" shade="Slate Gray" />
            </Column>
        </Row>
    );
};
 
export default App;


Step 9: Now again start the server and you will see the following output.

We have just decoupled the lighter shades into a reusable component, so you might expect the same result. The result will be different from what we intended. The separation of the components breaks our layout. 

All JSX elements in the Lightshades component are wrapped within a div. This div ends up breaking the layout since the browser sees this additional div as a part of our layout rather than as a wrapper for enclosing Html. Our browser is unaware that we added that div to avoid errors. Adding unnecessary divs could cause your layout to fail.

The layout breaks

You can easily fix this by wrapping your component’s JSX in a React Fragment instead. You can unify child nodes without adding an extra wrapper DOM element using React Fragments. The React fragment eliminates the instinct to wrap elements within a <div>. 

There are several ways to create and render fragments:

Using React.Fragment Syntax:

Javascript




// Modifying the LightShade component in app.js file
 
const Lightshades = () => {
    return (
        <>
            <Column>
                <Shadecard color="rgb(224,255,255)" shade="Light Cyan" />
            </Column>
            <Column>
                <Shadecard color="rgb(175,238,238)" shade="pale turquoise" />
            </Column>
            <Column>
                <Shadecard color="rgb(0,255,255)" shade="Aqua" />
            </Column>
            <Column>
                <Shadecard color="rgb(64,224,208)" shade="Turquoise" />
            </Column>
        </>
    );
};


The fragment property can be imported from React objects as shown below:

import React, {Fragment} from 'react' 

Javascript




// Wrapping the JSX elements of Lightshades using fragments
// Importing fragment properties from react object :
import React, { Fragment } from 'react';
 
const Lightshades = () => {
    return (
        <>
            <Column>
                <Shadecard color="rgb(224,255,255)" shade="Light Cyan" />
            </Column>
            <Column>
                <Shadecard color="rgb(175,238,238)" shade="pale turquoise" />
            </Column>
            <Column>
                <Shadecard color="rgb(0,255,255)" shade="Aqua" />
            </Column>
            <Column>
                <Shadecard color="rgb(64,224,208)" shade="Turquoise" />
            </Column>
        </>
    );
};


Short syntax <>: The cleanest and simplest way to use Fragments

Alternatively, fragments can be declared using a short syntax that looks like an empty tag.

Step 10:  Let’s us wrap the JSX elements of the Lightshades components in a react fragment using the short syntax. In app.js file, Wrap the elements of the Lightshades component using <>, replacing the div tag. 

Javascript




// Wrapping the JSX elements of Lightshades component using the short syntax
import React from 'react';
import './App.css';
 
const Row = ({ children }) => <div className="row">{children}</div>;
 
const Column = ({ children }) => <div className="col">{children}</div>;
 
const Shadecard = ({ color, shade }) => (
    <div className="card" style={{ backgroundColor: color }}>
        {shade}
    </div>
);
 
// Separating the light colors into a different component
const Lightshades = () => {
    return (
        <>
            <Column>
                <Shadecard color="rgb(224,255,255)" shade="Light Cyan" />
            </Column>
            <Column>
                <Shadecard color="rgb(175,238,238)" shade="pale turquoise" />
            </Column>
            <Column>
                <Shadecard color="rgb(0,255,255)" shade="Aqua" />
            </Column>
            <Column>
                <Shadecard color="rgb(64,224,208)" shade="Turquoise" />
            </Column>
        </>
    );
};
 
const App = () => {
    return (
        <Row>
            <Lightshades />
            <Column>
                <Shadecard color="rgb(0,206,209)" shade="Dark Turquoise" />
            </Column>
            <Column>
                <Shadecard color="rgb(0,128,128)" shade="Teal" />
            </Column>
            <Column>
                <Shadecard color="rgb(95,158,160)" shade="Cadet Blue" />
            </Column>
            <Column>
                <Shadecard color="rgb(47,79,79)" shade="Slate Gray" />
            </Column>
        </Row>
    );
};
 
export default App;


Output: Using any of the above methods will restore the desired layout of color palette. 

Using React Fragments 

Now, we will examine the DOM structure by adding an additional div and using a react fragment to wrap the JSX elements. 

DOM structure: Using a react fragment. 

DOM 

DOM structure: Using an extra div as a wrapper element.

DOM

The extra div clutters the DOM. This is a very simple scenario where we are enclosing the JSX elements within a div. The application becomes more complex if we add more components and we may end up rendering a significant number of unnecessary div tags. Therefore, the impact will be greater. 

Conclusion: With React Fragment, you can render multiple elements of a component without adding extra div tags. React Fragments enable us to write a cleaner, more readable code. It renders components faster and consumes less memory. It gives the expected component output. 



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads