Danny Guo Hacking away on sublimefund.org

Rendering sibling elements in React using Fragments

3 min read 862

Rendering Sibling Elements In React Using Fragments

One of the advantages of using React to render a user interface is that it’s easy to break up the UI into components. However, a common problem that arises is when we want to return sibling elements with no parent. React has a feature called Fragments that provides the solution.

The problem

If you aren’t familiar with the problem, consider this example.

function FAQ() {
    return (
        <p>Q. What is React?</p>
        <p>A. A JavaScript library for building user interfaces</p>
        <p>Q. How do I render sibling elements?</p>
        <p>A. Use Fragments</p>
    );
}

This code results in an error: Adjacent JSX elements must be wrapped in an enclosing tag.

The solutions

One option is to wrap the elements with a parent element.

function FAQ() {
    return (
        <div>
            <p>Q. What is React?</p>
            <p>A. A JavaScript library for building user interfaces</p>
            <p>Q. How do I render sibling elements?</p>
            <p>A. Use Fragments</p>
        </div>
    );
}

But this method introduces an extraneous element into the DOM, adding an extra level of nesting that we don’t actually need.

React v16.0 introduced another option, which is to return an array of elements.

function FAQ() {
    return [
        <p>Q. What is React?</p>,
        <p>A. A JavaScript library for building user interfaces</p>,
        <p>Q. How do I render sibling elements?</p>,
        <p>A. Use Fragments</p>
    ];
}

Now we need to add commas in between elements. More importantly, this code produces a key warning: Warning: Each child in a list should have a unique "key" prop. Adding a key to every element fixes the issue but is quite cumbersome.

function FAQ() {
    return [
        <p key="q1">Q. What is React?</p>,
        <p key="a1">A. A JavaScript library for building user interfaces</p>,
        <p key="q2">Q. How do I render sibling elements?</p>,
        <p key="a2">A. Use Fragments</p>
    ];
}

React v16.2 gave us a cleaner solution, which is to use Fragments.

function FAQ() {
    return (
        <React.Fragment>
            <p>Q. What is React?</p>
            <p>A. A JavaScript library for building user interfaces</p>
            <p>Q. How do I render sibling elements?</p>
            <p>A. Use Fragments</p>
        </React.Fragment>
    );
}

We no longer need to provide keys, we don’t need to add array commas, and we still avoid adding an extraneous DOM element because React.Fragment doesn’t become an actual element during rendering.

We can import Fragment to avoid having to fully write out React.Fragment.

We made a custom demo for .
No really. Click here to check it out.

import React, {Fragment} from "react";

function FAQ() {
    return (
        <Fragment>
            <p>Q. What is React?</p>
            <p>A. A JavaScript library for building user interfaces</p>
            <p>Q. How do I render sibling elements?</p>
            <p>A. Use Fragments</p>
        </Fragment>
    );
}

However, an even better method is to use the shorthand syntax for Fragments, which looks like empty tags: <> and </>.

function FAQ() {
    return (
        <>
            <p>Q. What is React?</p>
            <p>A. A JavaScript library for building user interfaces</p>
            <p>Q. How do I render sibling elements?</p>
            <p>A. Use Fragments</p>
        </>
    );
}

This gives us the same benefits as using React.Fragment, but we don’t need to import anything else, and our code looks cleaner.

The only thing that the shorthand syntax doesn’t support for now is adding a key. This could be problematic if you are creating a description list, for example. In this case, use the standard syntax.

function Dictionary(props) {
    return (
        <dl>
            {props.terms.map(({word, definition}) => 
                <React.Fragment key={word}>
                    <dt>{word}</dt>
                    <dd>{definition}</dd>
                </React.Fragment>
            )}
        </dl>
    );
}

We need to provide a key to avoid a key warning.

In most cases, however, the shorthand method is the best solution for our original problem of returning sibling elements. This solution has worked out well enough that Vue.js will also natively support the concept of Fragments when v3 is released.

Using Fragments

In the last two years, the JavaScript ecosystem has added widespread support for Fragments.

If you upgrade your dependencies, you will probably be able to use Fragments without any additional configuration.

Full visibility into production React apps

Debugging React applications can be difficult, especially when users experience issues that are difficult to reproduce. If you’re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, try LogRocket.

LogRocket is like a DVR for web apps, recording literally everything that happens on your React app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.

The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.

Modernize how you debug your React apps — .

Danny Guo Hacking away on sublimefund.org

Leave a Reply