Whatever the heck are React Fragments anyway?
Because apparently, empty tags mean something now.
This post was written with heavy AI assistance. The ideas are mine, but the words may not be. Here's why I stopped doing this.
If you’ve been working with React for a bit, chances are you’ve typed <>...</> more times than you can count. It’s one of those things that just… works. But have you ever stopped and asked:
“Whatever the heck is this thing, and why do I even need it?”
Let’s break it down — and explain what’s actually going on.
The Root of the Problem: JSX & React.createElement
React components must return a single parent element. That’s not just a style thing, it’s because of how JSX compiles under the hood.
When you write:
return (
<h1>Hello</h1>
<p>World</p>
);
React doesn’t see that as two HTML elements. JSX gets compiled to:
// Roughly this:
React.createElement('h1', null, 'Hello');
React.createElement('p', null, 'World');
That’s two separate calls, and React doesn’t know how to handle multiple root elements like that in a return statement. It needs a single parent node to wrap everything inside.
The Classic Fix: Wrapping in a <div>
Most folks fix this by adding a wrapper div:
return (
<div>
<h1>Hello</h1>
<p>World</p>
</div>
);
That works, but now you’ve introduced an unnecessary div into the DOM, and if you’re doing this in a loop or layout-heavy component, those wrappers add up quickly.
Enter: React.Fragment
A Fragment is React’s way of saying: “I need a wrapper, but don’t want to clutter the DOM.”
return (
<React.Fragment>
<h1>Hello</h1>
<p>World</p>
</React.Fragment>
);
JSX compiles this into something like:
React.createElement(React.Fragment, null,
React.createElement('h1', null, 'Hello'),
React.createElement('p', null, 'World')
);
React now sees one parent (the Fragment), and your rendered HTML stays clean, no stray divs in sight.
The Shorthand: <>...</>
Typing React.Fragment every time? Not so fun. Luckily, React gives us shorthand syntax:
return (
<>
<h1>Hello</h1>
<p>World</p>
</>
);
It behaves exactly the same, with one catch: You can’t pass props or use key with the shorthand.
So if you’re rendering fragments in a loop, stick with the full version:
items.map(item => (
<React.Fragment key={item.id}>
<h2>{item.title}</h2>
<p>{item.description}</p>
</React.Fragment>
));
TL;DR
- JSX compiles to React.createElement(…), which expects one root node.
- React Fragments let you group elements without extra DOM nodes.
<>...</>is shorthand forReact.Fragment.- Use the long form when you need to use key or props.
Hope that clears things up! Next time you write <>...</>, just know: it’s not magic, it’s just a helpful little wrapper with a fancy disguise.