Advanced React 1: Fragments
This is the start of an ongoing series exploring more advanced and esoteric features, paradigms, techniques with React. We'll deeply explore these topics as much as possible and examine use-cases of how they can help us build better web applications. Today's topic will be about React v16.2.0's new Fragment feature.
Before React v16, whenever we wanted to return a group of elements we needed to wrap our elements in an enclosing
<div>. React didn't had any abilities to circumvent this, so that means any component of yours with multiple children would always require a wrapper. This doesn't mean much if you have a small React application... But what if your application has multiple layers of nested children?
The Problem: Layered Complexity
Let's investigate the effects of what an additional wrapper could do.
⚠ Theoretical Thought Experiment Warning ⚠
Consider the above binary tree. Each node in the tree represents a React element, and let's you assume need to structure a React application like this. And let's say for some reason you'll eventually increase the depth of your element tree to a number much more than the number of nodes represented in the image.
We can represent this structure with a proof: For any given depth
d, the total number of nodes is
2ᵈ - 1. In a traditional application we need to be only concerned with
2ᵈ - 2 nodes to be present in the DOM to represent this structure.
However in older versions of React, at each level of nodes with children we need to add an additional wrapping
<div/> to render them. So our proof changes to
(2ᵈ - 1) + (2ᵈ⁻¹ - 2). This means we are adding
2ᵈ⁻¹ - 2 more nodes than we need to!
Imagine instead of a depth of 5, we use about 10 layers?
2¹⁰ - 1 gives us 1023 total elements vs. the 1533 elements we get from
(2¹⁰ - 1) + (2¹⁰⁻¹ - 2). Saving us 510 nodes from being rendered in the DOM! Obviously this carries great performance benefits in an extremely complex application needing so many DOM nodes.
This is where the Fragments API comes in. You can use it in React 16.2 and beyond, so upgrade today! You can review a excellent tutorial about fragments within the official React documentation. In short they allow us to render multiple children without a wrapper
import React from 'react'; const Fragment = React.Fragment; export const returnElements = () => ( <Fragment> <h1>Hi!</h1> <div>No wrapper around me! :]</div> </Fragment> ); // There's JSX syntax sugar for it too. // <> is translated to "React.Fragment" when used. export const returnElementsJSX = () => ( <> <em>JSX sugar is the best!</em> <div>No wrapper around me either! :]</div> </> );
With Fragments we can enjoy the performance benefits in a complex application as well as a reduction in clutter whenever we debug.
Not much else to say about it! The Fragments API is simple use and incorporate into your code. Next time we'll be exploring the new Context API that'll land in React 16.3.0. Or maybe the suspenseful future of async rendering? Cheers.