Multiple Layouts in React app with React Router v5

Shtanko Michael
3 min readMay 13, 2020

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:

MainLayout.tsx
AuthLayout.tsx

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.

AuthLayout’s routes

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.

MainLayout’s routes
PrivateRoute implementation example

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:

App.tsx

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!

--

--