Skip to main content

The Rules of JSX (Part 1): Single Root Element and Fragments #20

πŸ“– Introduction​

After mastering JSX attributes, we now encounter one of the most fundamental and strictly enforced rules of writing JSX. When you first try to return multiple elements from a component, you will inevitably run into an error: "JSX expressions must have one parent element."

This article explains why this rule exists and introduces the two primary solutions: wrapping elements in a container div and using the more elegant and efficient Fragment syntax (<>...</>) to solve the problem without adding extra nodes to the DOM.


πŸ“š Prerequisites​

Before we begin, please ensure you have a solid grasp of the following concepts:

  • React Components: You should be comfortable creating a basic React component that returns a single JSX element.
  • JavaScript Functions: Understanding that a JavaScript function can only have one return value.

🎯 Article Outline: What You'll Master​

In this article, you will learn:

  • βœ… The Single Root Element Rule: Understanding why a React component must return a single element.
  • βœ… The Problem with Multiple Elements: Seeing the error that occurs when you try to return adjacent elements.
  • βœ… Solution 1: The div Wrapper: The most straightforward way to solve the problem and its main drawback.
  • βœ… Solution 2: The Power of Fragment: Using <React.Fragment> or the shorthand <> to group elements without affecting the DOM.
  • βœ… Practical Use Cases: Knowing when to use a div versus when to use a Fragment.

🧠 Section 1: The "One Return Value" Rule​

The core reason for this JSX rule is rooted in plain JavaScript. A JavaScript function can only return a single value.

// This is valid - returns one object
function getOneThing() {
return { message: 'Hello' };
}

// This is INVALID - you can't return two separate objects
function getTwoThings() {
// return { message: 'Hello' }, { message: 'World' }; // Syntax Error!
}

As we learned previously, JSX is just syntactic sugar for React.createElement() calls, which return JavaScript objects. Therefore, a React component's return statement can only return a single JSX element, because it's ultimately returning a single object.

Trying to return two adjacent elements is like trying to return two values from a functionβ€”it's not allowed.

The Problem in Practice: This code will produce an error:

// code-block-1.jsx
// This will cause an error!
function Post() {
return (
<h1>About This Blog</h1>
<p>It's a great blog!</p>
);
}

The error message will be clear: JSX expressions must have one parent element.


πŸ’» Section 2: Solving the Problem​

There are two common ways to fix this.

2.1 - Solution 1: The div Wrapper​

The most intuitive solution is to wrap the adjacent elements in a single parent container, like a div.

// code-block-2.jsx
// This works!
function Post() {
return (
<div>
<h1>About This Blog</h1>
<p>It's a great blog!</p>
</div>
);
}

This works perfectly because the component is now returning a single <div> element, which contains the other elements as children.

The Drawback: This approach introduces an extra <div> into the DOM. While often harmless, it can sometimes interfere with CSS styling (especially with Flexbox or Grid layouts) or create invalid HTML (for example, you can't put a <div> inside a <table> in certain places). This is often referred to as "div-itis."

2.2 - Solution 2: React.Fragment​

To solve the "div-itis" problem, React provides a special component called React.Fragment. A Fragment lets you group a list of children without adding an extra node to the DOM.

// code-block-3.jsx
import React from 'react'; // or import { Fragment } from 'react';

function Post() {
return (
<React.Fragment>
<h1>About This Blog</h1>
<p>It's a great blog!</p>
</React.Fragment>
);
}

This code is valid, and when it renders, the <h1> and <p> will be direct siblings in the DOM, with no wrapper div.


πŸ› οΈ Section 3: The Shorthand Syntax: <>​

Writing React.Fragment is a bit verbose, so JSX offers a much cleaner, shorter syntax for it: <>...</>.

This is the most common way to use Fragments today.

// code-block-4.jsx
// The modern, clean way
function Post() {
return (
<>
<h1>About This Blog</h1>
<p>It's a great blog!</p>
</>
);
}

This code is functionally identical to the React.Fragment example but is easier to read and write.


πŸš€ Section 4: When to Use the Full Fragment Syntax​

There is one important case where you cannot use the shorthand <> syntax: when you need to pass a key prop to the Fragment.

This typically happens when you are rendering a list of Fragments in a loop. React requires a unique key for each item in a list to track it efficiently. The shorthand syntax does not support attributes, so you must use the full React.Fragment syntax.

// code-block-5.jsx
import React from 'react';

const articles = [
{ id: 1, title: 'First Post', content: 'This is the first post.' },
{ id: 2, title: 'Second Post', content: 'This is the second one.' },
];

function ArticleList() {
return (
<>
{articles.map(article => (
// We need a key here, so we must use the full Fragment syntax
<React.Fragment key={article.id}>
<h2>{article.title}</h2>
<p>{article.content}</p>
</React.Fragment>
))}
</>
);
}

export default ArticleList;

In this example, using <React.Fragment key={article.id}> is necessary. Trying to do <key={article.id}> would result in a syntax error.


✨ Section 5: Best Practices​

Best Practices:

  • Default to Fragments: When you need to return multiple elements, your first choice should be the shorthand Fragment (<>...</>).
  • Use div for Semantic Grouping or Styling: Only use a div or another container element if you actually need a wrapper for styling (e.g., applying a CSS class, a margin, or using it as a flex container) or for semantic HTML reasons.
  • Use <React.Fragment> for Lists: Remember to switch to the explicit <React.Fragment> syntax when you need to provide a key to a list of grouped elements.

πŸ’‘ Conclusion & Key Takeaways​

You've now learned one of the most important rules of JSX and the elegant solution React provides. Understanding when and why to use Fragments will help you write cleaner, more efficient components.

Let's summarize the key takeaways:

  • Single Root Rule: A React component must return a single root element because a JavaScript function can only return one value.
  • div Wrappers Work but Add Nodes: Wrapping adjacent elements in a div solves the problem but adds an unnecessary element to the DOM.
  • Fragments are Invisible Wrappers: React.Fragment (or <>...</>) lets you group elements without adding any extra nodes, keeping your DOM clean.
  • Shorthand is Preferred: Use the <>...</> syntax unless you need to pass a key prop, in which case you must use <React.Fragment>.

Challenge Yourself: Create a Glossary component that renders a list of terms and their definitions. The HTML structure for a glossary uses <dl> (description list), <dt> (term), and <dd> (definition). Each term-definition pair (<dt> and <dd>) should be grouped together. Use a Fragment with a key to render the list correctly without adding extra divs inside your <dl>.


➑️ Next Steps​

With the single root element rule mastered, we'll move on to another core rule of JSX. In the next article, "The Rules of JSX (Part 2): The importance of closing all tags and other syntax rules", we will cover the other syntax requirements that make JSX a predictable and robust way to write UI.

Thank you for your dedication. Stay curious, and happy coding!


glossary​

  • Root Element: The single, top-level element that a component returns. All other elements must be nested inside it.
  • Fragment: A special React component that allows you to group a list of children without adding extra nodes to the DOM.
  • Shorthand Fragment Syntax (<>...</>): A concise way to write a React.Fragment that does not require a key.

Further Reading​