Fragments in React 16

Imagine your React app needs to render a list of items, for example:


<ul>
  <li>Private Item 1</li>
  <li>Private Item 2</li>
  <li>Private Item 3</li>
  <li>Public Item 1</li>
  <li>Public Item 2</li>
  <li>Public Item 3</li>
<ul>

Code snippet 1.

In this list you have two types of items: private and public. They are grouped together and rendered by different React components. Private items are rendered by PrivateListItems React component and public items by PublicListItems React component.

The problem is that both PrivateListItems and PublicListItems components need to return multiple elements, for example:


const PrivateListItems = () => (
  <li className="list-group-item">Private Item 1</li>
  <li className="list-group-item">Private Item 2</li>
  <li className="list-group-item">Private Item 3</li>
);

Code snippet 2. Anti-pattern.

Unfortunately, this is not possible in React 16.

The rule is: a render() method in a React component must return only one element, not three li elements. We could wrap all three li elements in one parent element and return that element instead, but this will break our ul list.

So the question is: how can React component render three li elements without rendering a parent element?

This is what fragments in React are for. Let's demonstrate how to use fragments with the help of a simple React application:

Application screenshot
Figure 1. Our application.

You can find the full source code in this GitHub repository.

Our application is going to render a list of items. This list will be made of private and public items. Private items will be rendered by PrivateListItems component and public items will be rendered by PublicListItems component.

Our application will be made of three React components:

  1. App
  2. PrivateListItems
  3. PublicListItems

App component is a container component - it encapsulates our entire React application, and renders PrivateListItems and PublicListItems as child components.

Let's create our App component first:


import React from "react";
import PrivateListItems from "./PrivateListItems";
import PublicListItems from "./PublicListItems";

const App = props => (
  <div class="container">
    <div class="row">
      <div class="col-sm mt-5">
        <ul class="list-group">
          {props.userHasPermissions && <PrivateListItems />}
          <PublicListItems />
        </ul>
      </div>
    </div>
  </div>
);

export default App;

Code snippet 3. App.js

Our App component renders three div elements with class names that you might recognize if you're familiar with Bootstrap. Bootstrap helps us create layout for our page.

Now let's focus on the ul element:


<ul class="list-group">
  {props.userHasPermissions && <PrivateListItems />}
  <PublicListItems />
</ul>

Code snippet 4. App.js

The ul element has two child components: <PrivateListItems /> and <PublicListItems />.

As we've discussed earlier, our ul list is made of public and private li elements. We have two separate React components responsible for rendering those items:

  • <PrivateListItems /> renders only private items.
  • <PublicListItems /> renders only public items.

Why do we want to separate those items into different React components? Imagine a scenario where all users can see public items, but only user with additional permissions can see private items. For example, only authenticated users can see items that are private to them.

Notice that use props.userHasPermissions prop and logical operator && to decide if we want to render <PrivateListItems /> component:


{props.userHasPermissions && <PrivateListItems />}

Code snippet 5. App.js

The userHasPermissions is a prop with a boolean value. When the value is true our App component will render <PrivateListItems /> component as a child. When the value is false our App component will not render <PrivateListItems /> component.

Now when we render our App component we can pass userHasPermissions prop to it only when the user is authenticated, for example:


import React from "react";
import ReactDOM from "react-dom";
import App from "./components/App";

ReactDOM.render(<App userHasPermissions />, document.getElementById("root"));

Code snippet 5. index.js

Change userHasPermissions to userHasPermissions={false} and our App component will only render PublicListItems component.


ReactDOM.render(<App userHasPermissions={false} />, document.getElementById("root"));

Code snippet 6. index.js

Now let's take a look at our PrivateListItems component:


import React, { Fragment } from "react";

const PrivateListItems = () => (
  <Fragment>
    <li className="list-group-item">Private Item 1</li>
    <li className="list-group-item">Private Item 2</li>
    <li className="list-group-item">Private Item 3</li>
  </Fragment>
);

export default PrivateListItems;

Code snippet 7. PrivateListItems.js

It returns Fragment that wraps our three li items. What will Fragment type render into the DOM? Nothing! And that's exactly what we want our PrivateListItems component to do: render only three li items, without rendering a parent element.

You can think of a Fragment type as an element that is invisible to the DOM.

Now let's create our PublicListItems component:


import React from "react";

const PublicListItems = () => (
  <>
    <li className="list-group-item">Public Item 1</li>
    <li className="list-group-item">Public Item 2</li>
    <li className="list-group-item">Public Item 3</li>
  </>
);

export default PublicListItems;

Code snippet 8. PublicListItems.js

Wait, do we have a typo there? No, we don't! The empty tags <> and </> is a short syntax for declaring Fragment in React 16.

In other words, this:


<>
  <li className="list-group-item">Public Item 1</li>
  <li className="list-group-item">Public Item 2</li>
  <li className="list-group-item">Public Item 3</li>
</>

Code snippet 9. PublicListItems.js

Is the shorter version of this:


<Fragment>
  <li className="list-group-item">Public Item 1</li>
  <li className="list-group-item">Public Item 2</li>
  <li className="list-group-item">Public Item 3</li>
</Fragment>

Code snippet 10. PublicListItems.js

What's the difference between those two syntaxes if the result is the same? There is a difference. <Fragment> syntax supports a key attribute, while <> syntax - doesn't.

Now you know how to use fragments in React 16!

Thank you for reading this React tutorial.

Please take a look at the complete source code on GitHub and the live version of our app.

I hope you've enjoyed this tutorial and I would love to hear your feedback in the comments. You can get in touch with me via Twitter and email.

Artemij Fedosejev

Artemij Fedosejev