I bet you read that title & thought “Whoa that sentence is a Fragment!” 😜 Haha what the title should say is “I learned about React Fragments”. Anyways I know what you’re asking “What are React Fragments?!?” They are a common pattern for a component to return a list of children.
Note: React 16 added support for returning an array of elements from a component’s
rendermethod & as of React 16.2 provides a first-class
Fragmentcomponent that can be used in place of arrays.)
I just learned about them (I know I’m a little late to the game) & ran into a good use case where it came in handy!
So I’m setting up my routes & want to make certain routes are available only when a User is Logged & vice-versa.
So I come up with something like & this works perfectly but this brings up a small issue. When running the above setup if you open up your browser console you will notice the error below.
The reason React is throwing this error is because the
Switch component only expects
Route components children. 🤔 Hmmmm so lets try this. Let’s wrap each Route in it’s own conditional & see if this fixes our error.
Andddd yup it fixes our error! Hmm but this doesn’t seem like the best solution because it isn’t DRY & contains code smells. If we go with this solution we’ll have to include the
isLoggedIn conditional for every single new Route. Also our code will be computing the same condition for x amount of routes that we have(This is a code smell 😷). So what can we do? I really like our first example because it was DRY & it didn’t contain a code smell but wrapping our routes in a
div gives us an ugly looking error. I know what your saying to yourself, “I wish there was a way you can wrap stuff in React magically!”.
React Fragment to the Rescue!!! We can now keep what we had in our first example & just replace the
div with Fragment (imported from ‘react’).
See note below on why we’re importing a custom Switch component.
See a live example here: https://codesandbox.io/s/7k9rn30jmq?module=%2Fsrc%2Fconfig%2Froutes.js&view=editor
Yay No more errors! That about WRAPS up this post! 😉
For more puns and code tips follow my journey on twitter @clickclickonsal
This article originally published on my Medium publication
Edit (February 27th, 2018)
Note: @leandroaps ran into a issue where his route was always getting rendered. It turns out React-Router’s Component doesn’t have support for routes wrapped in Fragments. While the code “seems” to work fine it breaks when trying to add a “catch all” route. I looked into this and found a Github related issue & came across a workaround for this problem here. The workaround is to wrap the react-router Switch component that includes logic to flatten the routes out. I’ve updated the code sandbox above to include this fix so you can see how it’s implemented. Thanks @bripkens for the your Open Source contributions! 😃