What are fragments?

Often times when constructing JSX markup, we might come across the need to encapsulate it around a <div> container as shown below:

function App() {
   return (
      <div>
         <h1>A heading</h1>
         <p>A paragraph</p>
      </div>
   );
}

This is because we can't return multiple JSX elements from a component as it is, like in the following snippet:

function App() {
   return (
      <h1>A heading</h1>
      <p>A paragraph</p>
   );
}

Remember that a JSX element is simply a call to createElement() and so returning multiple elements means to be returning multiple such expressions as follows:

function App() {
   return (
      React.createElement('h1', null, 'A heading')
      React.createElement('p', null, 'A paragraph')
   );
}

Clearly, this code is invalid.

Using <div>s has long been used in React, but actually there's no need to. It unnecessarily populates the DOM by introducing redundant <div>s into it. We have a much better way of grouping together React elements into a single element — say hello to fragments.

A fragment is a means of grouping together multiple React elements into a single React element.

Just how the DOM has the idea of document fragments to group DOM nodes into one single node that itself doesn't show up in the DOM, React has one as well.

In React, a fragment operates much like a DOM fragment. It groups multiple React elements into a single unit which can then be treated as a single element.

However, unlike DOM fragments, fragments in React do show up in the virtual DOM tree.

In addition to this, fragments could have keys. However, at the time of this writing, we can't provide them just about any arbitrary prop because there's absolutely no point in doing so — the prop doesn't get to reach anywhere!

Let's now talk about how to create a fragment in React.

Creating fragments

The react library has a named export called Fragment, which represents the fragment element type.

To create a fragment out of this, we need the same old createElement() function used to create other kinds of elements in React.

The first argument of the function is Fragment, and usually since there's no need to provide any prop to a fragment element, the second argument is null, followed by all the children of the fragment.

Let's take an example.

In the following code, we use a fragment to solve the error in the code above where we had an <h1> element followed by a <p> element:

import React, { Fragment } from 'react';

function App() {
   return (
      <Fragment>
         <h1>A heading</h1>
         <p>A paragraph</p>
      </Fragment>
   );
}

When the <Fragment> here gets rendered out on the document, only <h1> and <p> are rendered — the fragment itself, just like components, doesn't get output in the DOM.

Live Example

If we don't want to directly access Fragment, we'd rewrite the code as follows:

import React from 'react';

function App() {
   return (
      <React.Fragment>
         <h1>A heading</h1>
         <p>A paragraph</p>
      </React.Fragment>
   );
}

There's even a more compact syntax to specifically a fragment in JSX. That is to use <> and </>, without any text inside the tags themselves.

Note that there's no need to manually import Fragment when using the syntax <></>.

The code above could be identically represented as follows:

function App() {
   return (
      <>
         <h1>A heading</h1>
         <p>A paragraph</p>
      </>
   );
}

Live Example

Peaches and cream!

Using keys with fragments

Except for key, there's no point of providing any other prop to a fragment because it isn't entertained by the fragment.

The key prop makes sense because fragments do show up in the virtual DOM tree and so, if we render a list of fragment elements, React will throw the same key warning to us unless we add a key to each fragment element.

And this could've only been possible if fragments were to entertain keys, which they do.

When using keys in fragments there's an extremely important thing to remember. That is, key can't be provided if we denote a fragment as <>...</>

So fo example, the following code is invalid:

function App() {
   return (
      <key={0}>
         <h1>A heading</h1>
         <p>A paragraph</p>
      </>
   );
}

If we want to provide keys to fragments, we are bound to use the <Fragment> syntax, as shown below:

import React, { Fragment } from 'react';

function App() {
   return (
      <Fragment key={0}>
         <h1>A heading</h1>
         <p>A paragraph</p>
      </Fragment>
   );
}

Simple.

Why is it not possible to use key in <>?

Probably because doing so will lead to ambiguous JSX code.

Just consider the following markup and ask yourself: does this seem right?

Formally, if key was allowed to be used inside <>, it would've meant that the syntax of opening tags in JSX had to be changed to cater to this special case. But not just this, the syntax definition of closing braces would've had to be modified as well.

And even if we get past all of this formality, somehow, we'd still not find this style any neat. As you might agree, it looks a bit (a little bit) awkward.

Note that this might get changed in the future, but if it doesn't, at least now we have a good reason to accept this design choice.