Multiple Layouts in React app with React Router v5
How to use different layouts with React Router v5 to prevent remounting
Working on large projects we are constantly faced with the need to separate our application into sections, each of which uses its own layout. There are many cases when we need to use several layouts on a site. The simplest example is when we need to separate the administrative part from the client part or, for example, slightly change the page layout for an unauthorized user. In this article I would like to talk about how to use many layouts in React application using React Router v5 without redundant mountings.
Before I start, I would like to clearly define the goals of this article:
- To prevent remounting layouts on route changes (within the same layout), because this behavior gives an overhead, and can also break transitions, etc.
- To prevent mounting of a layout, which includes the current route, which a user does not have access to (due to permissions or authorization)
Let’s imagine that there are two layouts in out application: MainLayout
and AuthLayout
. The first layout is needed for the main part of the site that authorized users can see, and the second one for registration, login, password recovery pages, etc.
In this example, MainLayout
contains the sidebar, header, footer and page content, and AuthLayout
contains only the right panel with the form inside.
You can see sample code for the layouts below:
So, now we need to tell React that we want to use different layouts for different routes. By using React Router v5, route declarations are performed using Route
component. This component is able to take an array of paths, which greatly facilitates the use of different layouts. We can create Route
component thus which will fire when the current URL matches one of the specified paths and mount the layout first, and only then the target page itself.
So we have already achieved one of our goals, namely, when switching between /login
and /register
routes, AuthLayout
will not mount again, but will only change its children
.
But what to do when we need to deny access to certain pages? Here we can use the classic React approach and create a simple PrivateRoute
component. But we will not use it for each individual route, but for the whole layout, because otherwise React will first mount the layout and only then get to PrivateRoute
with the target page and check access to it.
We have achieved all our goals, now React will not even mount the layout if a user does not have access to its pages. But there is a problem. As you can see, we are forced to duplicate each route, first for the layout, and then for the page itself. With the increase in the number of routes, their support will become a large problem. I suggest using static routes to configure application’s routing.
In this case, the routes will be configured approximately as follows:
This approach allows you to use an unlimited number of templates without any overhead.
That’s it! I hope this article was helpful for you. For more information you can use this repository.
If you have any questions or suggestions, let me know in the comments. Happy coding!