It’s is a common practice in React to render dynamically multiple sibling components. When returning JSX from a React component we need to maintain the tree structure of the HTML elements. The component must return at most 1 top-level node. Fragments let us deal with this problem in a very effective way.

The problem

Let’s start by understanding the problem that Fragments are meant to solve.

function App() {
  return (
    <div>
      <ul>
        <Users />
      </ul>
    </div>
  );
}

export default App;

const Users = () => {
  return (
      <li>Tommy</li>
      <li>Mike</li>
      <li>Anna</li>
  )
}

This piece of code has an error that lies in the Users component.

Error

As you can see even our IDE is complaining that ‘JSX expressions must have one parent element’. We’re trying to return three elements with no parent, hence the code won’t compile. We need to wrap those elements with something. Let’s use div for now.

The solution

function App() {
  return (
    <div>
      <ul>
        <Users />
      </ul>
    </div>
  );
}

export default App;

const Users = () => {
  return (
    <div>
      <li>Tommy</li>
      <li>Mike</li>
      <li>Anna</li>
    </div>
  )
}

Now the error went away and everything is seemingly fine, but let’s take a look at the DOM structure of our application. Do you see something strange?

DOM structure 1

That’s right the li elements are wrapped with that extra div element that we were forced to add. Instead of using div, we can use the Fragment.

React Fragment

import React from "react";

function App() {
  return (
    <div>
      <ul>
        <Users />
      </ul>
    </div>
  );
}

export default App;

const Users = () => {
  return (
    <React.Fragment>
      <li>Tommy</li>
      <li>Mike</li>
      <li>Anna</li>
    </React.Fragment>
  )
}

Let’s check out the DOM structure again to see if the problem went away.

DOM structure 2

Can you spot the difference? That’s right. Fragments let us wrap nodes without rendering extra element to the DOM. It’s a pretty convenient tool.

Short syntax

You can use a short syntax for most of the use cases. You can use it in the same way you would use any other element.

Instead of using <React.Fragment>…</React.Fragment>, we can simply use <>…</>

import React from "react";

function App() {
  return (
    <div>
      <ul>
        <Users />
      </ul>
    </div>
  );
}

export default App;

const Users = () => {
  return (
    <>
      <li>Tommy</li>
      <li>Mike</li>
      <li>Anna</li>
    </>
  )
}

One important thing to note here is that the short syntax doesn’t support passing attributes to it. In some cases, you may wanna pass a key property to the parent level element. This usually happens when using JS map()

import React from "react";

const USERS = [{ name: 'Tommy', age: 16 }, { name: 'Mike', age: 54 } , { name: 'Anna', age: 21 }]

function App() {
  return (
    <dl>
      {USERS.map((user, index) => (
        <React.Fragment key={index}>
          <dt>{user.name}</dt>
          <dd>{user.age}</dd>
        </React.Fragment>
      ))}
    </dl>
  );
}

export default App;

Personally, I find using Fragments very helpful. Try to use them yourself whenever possible. It’s a good practice.

Avatar photo
👋 Hey, I'm Dawid Budaszewski
Hello! I'm Dawid. I'm a full-stack developer with a couple of years of experience under my belt. I spent most of my career working with React. Now it's time to pass the knowledge onto somebody else!

💬 Leave a comment

Your email address will not be published.

We will never share your email with anyone else.