DEV Community

Cover image for How do React Fragments work under the hood?
Nick | React tinkerer ⚛️
Nick | React tinkerer ⚛️

Posted on

How do React Fragments work under the hood?

React aims to stay neat and clean that's why fragments are out there. They allow getting rid of excess wrappers while rendering multiple elements!

That's pretty cool, but how do they work under the hood?

👉 React Fragment is just a React Element of a special type!

JSX is a syntax sugar for calling React.createElement
This function expects only three possible groups of types:

  • tag name for basic HTML elements
  • class/function for user-defined components
  • React fragment type
// what you write
const Items = () => {
  return (
    <>
      <li>First element</li>
      <li>Second element</li>
      <li>Third element</li>
    </>
  );
}

// what React gets after babel transpilation
const Items = () => {
  return React.createElement(
    React.Fragment, 
    null,
    React.createElement("li", null, "First element"),
    React.createElement("li", null, "Second element"),
    React.createElement("li", null, "Third element")
  );
};
Enter fullscreen mode Exit fullscreen mode

👉 How does React work with fragments?

After all, there are no corresponding DOM elements!

React doesn't need real DOM elements to deal with fragments.
It forms a virtual DOM instead 💡

// Items() return this
{
  "type": Symbol(react.fragment),
  "key": null,
  "ref": null,
  "props": {
    "children": [
      {
        "type": "li",
        "key": null,
        "ref": null,
        "props": {
          "children": "First element"
        },
      },
      // ...
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

ReactDOM, in turn, ignores fragments and renders all children without any wrappers.

👉 Verify that it works yourself!

Go to reactjs.org and paste the Items component.

If DOM looks the same as here 👇, you've done a great job!

<div id="___gatsby">
  <li>First element</li>
  <li>Second element</li>
  <li>Third element</li>
</div>
Enter fullscreen mode Exit fullscreen mode

P.S. Follow me on Twitter for more content like this!

Discussion (10)

Collapse
fjones profile image
FJones

It's worth noting that react now supports returning arrays from components/render (since a common use case for fragments was to wrap adjacent elements). The stark difference with explicit Fragments is that they allow adding a key prop when iterating, which lets react to optimize over it.

I would also suggest an example of how Fragment works for that purpose.

Collapse
fromaline profile image
Nick | React tinkerer ⚛️ Author

Yep, you're right!
I'll consider adding this info to the article!
Thanks for the suggestion, I really appreciate it 🙏🏻

Collapse
loopmode profile image
Jovica Aleksic • Edited on

I don't think react will optimize anything in this case, it's just that you must pass key props on array children by design, or you'll suffer at least warnings. If your array children are static and stable anyways, then you can safely ignore the warnings. Or: use a fragment instead!
The point is, arrays and fragments are not just the same thing, they have different concepts. Arrays are meant to represent dynamic children, that is: content elements that are based on dynamic data.
Fragments are meant to represent static content, that is: content that does not change dynamically, or: content that is basically hard coded.
Yes, in the end they perform similar. If you use an array without keys and ignore the warnings, then your perf will suffer and you'll have bugs when e.g users sort/drag elements. Same if you would use fragments for such dynamic content, however in that case you'd not even get any warnings.

So use fragments for static content that will not change, and enjoy the freedom of not having to specify keys.
Use arrays and provide keys for content that is rendered by iterating dynamic data.

Collapse
maksimrv profile image
Maksim

After all, there are no corresponding DOM elements!

DOM DocumentFragment is an inspiration for React fragment

Collapse
fromaline profile image
Nick | React tinkerer ⚛️ Author

May you provide a proof, please?
I ask, because these two things have nothing to do with each imo.
Also, DocumentFragment has no corresponding DOM element too.

Collapse
maksimrv profile image
Maksim

because these two things have nothing to do with each imo

Conception absolutely the same. I bet that React team when tried to create element which should solve the problem "No wrapper" they came to conecption which existed long time in DOM. You can create document fragment and manipulate it as regualr element, add child nodes, query etc. But when you append document fragment to a DOM tree it would "disappear" and parent node of document fragment would be parent node of document fragment's childern. The same you can see in React virtual tree where Fragment represent part of the virtual document. So my response was just to clarify a little bit a phrase from you article :) Becuse sometimes it's easy to clarify virtual DOM conceptions using "real" DOM

Collapse
fromaline profile image
Nick | React tinkerer ⚛️ Author

Thanks!
I’m glad you like it 😊

Some comments have been hidden by the post's author - find out more