Today I want to tell you about a very interesting way of organizing the React Router routes so that we do not have to resort to writing the routes of our application one by one using
<Route> components, which ends in gigantic structures of the type:
In addition, this will serve as a starting point to add new logic to them as a role check or separate their layouts based on a parameter that we determine.
This article is based on the idea proposed in the documentation of the React Router library whose example you can consult at this link.
To complete the article at the end of it you have a link to the CodeSandbox that I have created so that you can play with it.
So, without further ado, let’s see it!
The first thing we will do is start from an application that has the typical route structure that I mentioned before:
Basically in the application we have 3 defined routes each one associated to a component and a
Menu component in charge of painting the links to navigate between each one.
However, as our application grows the number of routes that the
<Switch> component can hold can be excessive, so the idea of this article is to show how we can simplify the generation of this component.
Defining a route object
The first thing we are going to do is to abstract the concept of the route in an object, so that we can later automate its generation within the Switch component.
Since we are working with a very simple application, an object that defines a route will have two properties:
component, to identify the component associated with the route,
path, that is, the string to access the path.
That said, we will create a
routes.js file (I usually create it inside the
config/routing folder where we define each of the routes in our application:
In this way, we will define each route specifying its two properties and we will export an array with all the ones we have defined.
Also, in order to specify the
component property of each path, I am accessing the
views object, imported from the
components/views/index.js file and that looks like this:
Using our route objects
Once we have defined the routes of our application, now it will be enough to use the array that we are exporting from our
routes.js file inside the
Switch component so that we can go through it to automatically create the
From now on, adding new routes to our application is as simple as creating its component and adding its corresponding object within the
Well well. But that’s not all, below we will see some interesting things we can do.
In order not to have the
paths of the routes written to fire in the application, I usually define them in the
config/routing/paths file as constants, so that I don’t have to write the string every time I want to redirect to the path:
So in the creation of our objects for each route and their corresponding links within the
Menu component they are the ones we use:
Specifying private routes easily
Now that we have abstracted our routes, carrying out checks to access them is very simple.
For example, suppose we want to specify public routes and private routes within our application, so that to access a private route we must be logged in.
The first thing we will do is create its corresponding component, which I will call
PrivateView in the project whose CodeSandbox I remind you of at the end of the article.
Next, we are going to vitaminize our routes to add a property that indicates whether or not this route is private:
And we will create our own
Route component from the
Route component of the React Router library so that it is in charge of checking if a route is private or not:
Basically, instead of using the
component property of the
Router component, what I do is take advantage of its
render property to check if the path is accessible or not.
userIsLoggedIn utility is a function that returns
false depending on the state of the user visiting the page.
Now it is only enough to use this component inside our
App.js file instead of the one provided by React Router and we will have our protected routes:
Although the same result can be obtained by declaring the routes normally. this route configuration works equally well with React.lazy and Suspense to allow us to lighten the size of our main bundle, serving the components associated with the route on demand. To do this, simply modify our
components/views/index.js file to use
React.lazy and surround the definition of our routes in the
App.js file with
As you can see, this system can be very suitable for large applications where there are multiple routes and whose “layouts” differ depending on the user or the type of content.
All of this can be abstracted by defining paths as objects, so that we can group all the logic together and don’t have to repeat it over and over as we add new paths and components.
If you want to see the complete project working I leave you the link to a CodeSandbox so you can mess with it:
In addition, you will surely find the odd hit to this system, so if you feel like it, leave your opinion in the comments to discuss it and continue learning.
Do you want to read more articles like this?
If you liked this article I encourage you to subscribe to the newsletter that I send every Sunday with similar publications to this and more recommended content: 👇👇👇