Using React Fragments
As a React and CSS enthusiast, I started to encounter issues with styling the layout of my React apps. React requires all components to return a single element at a time, which requires developers to wrap everything in either span
or div
tags. For this reason, I would see loads of div
block elements wrapping around all of my actual content as children when looking at the virtual DOM of my apps.
This can be frustrating when styling and positioning the layout of the app, because all of these extra div’s come with their own inherited block element styling and properties. I would find myself manually overwriting all of these properties in my CSS file, which adds to the already large amount of superfluous lines of code in each app. I started to research easier ways to strip div
elements of their properties, and instead found the gorgeous Fragment
component introduced in React 16.2.
The problem that fragments solve
Up until React v16, each component had to return only one single element:
//will break
class Container extends React.Component {
render() {
return (
<p>Hello</p>
<p>World!</p>
)
}
}//only returns one element
class Container extends React.Component {
render() {
return (
<div>
<p>Hello World!</p>
</div>
)
}
}
Most React enthusiasts solve this problem by wrapping all of the elements in one containing element, such as a span
or a div
. However, on large applications with whole suites of components this can very quickly lead to unnecessary and redundant HTML tags with no purpose in the DOM. These divs can also make styling and layout problems farther down the road. The resulting DOM render from the above snippet will look like this:
<div>
<p>Hello World!</p>
</div>
Fragments in React 16.2
React 16.2 introduced the Fragment
:
“Fragments look like empty JSX tags. They let you group a list of children without adding extra nodes to the DOM” — React 16.2 release
The Fragment
is imported as a component from the react
module, and is used just like any other JSX element. However, the key feature of Fragment
components is that they do not add any extra HTML tags into the DOM. So, in this way, you can return one single Fragment
component that wraps around all of your other content just like you normally would with div
or span
. However, with a Fragment
, the application will render in the DOM with no extra HTML tag wrapping your elements.
Using a Fragment
First, we import Fragment
just like we import Component
from react
:
import React, { Fragment } from 'react';
And then we use it just like any other React component. Here it is used in a React representational component using an arrow function. Side note: Notice that we can use a () instead of {} after the arrow. This is because parentheses comes with implicit returns when wrapped around a function block. For this reason and for the sake of readability, I like to use parentheses over curly braces whenever possible.
//implicit return
const Container = () => (
<Fragment>
<p>Hello</p>
<p>World!</p>
</Fragment>
)//explicit return
const Container = () => {
return (
<Fragment>
<p>Hello</p>
<p>World!</p>
</Fragment>
)
}
The resulting DOM render from the Container
component will look like this:
<p>Hello</p>
<p>World!</p>
Beautiful!!
However… here’s a little something extra weird.
React 16.2 also introduced a special fragment syntax that is definitely… something. These two code blocks produce the same result:
const Container = () => (
<Fragment>
<p>Hello</p>
<p>World!</p>
</Fragment>
)const Conatiner = () => (
<>
<p>Hello</p>
<p>World!</p>
</>
)
Weird, right? But I guess it comes down to personal preference. I personally prefer the more explicit Fragment
syntax. This is because even though I love opportunities to simplify and shorten my code, I’m not willing to sacrifice readability. It’s also important to note that you won’t be able to pass down any props if you use this special syntax; you’d have to use the explicit Fragment
component in that case.
Conclusion
I just recently discovered the use of Fragments, and I’m already really excited for this straightforward way to eliminate unnecessary, superfluous div
elements. Not only do they clean up a lot of component code, they also alleviate all the extra HTML container tags that React applications have been known for.