DEV Community

Cover image for Multiple Layout In React Router
Selva kumar
Selva kumar

Posted on • Updated on

Multiple Layout In React Router

I have come across several scenarios where I needed to create views/pages that had different layout structures in real-time applications like real estate, eCommerce. Recently I had the opportunity to create a multi-layout application and just want to share it.

Initial setup

Create a simple React app that changes depending on the current route:

import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
import Router from "components/router";

const MyApp = props => (
  <BrowserRouter>
      <Router />
  </BrowserRouter>
);

ReactDOM.render(<MyApp />, document.getElementById("app"));
Enter fullscreen mode Exit fullscreen mode


javascript
The component defines all the possible routes of our app and their corresponding components:

import React from "react";
import { Route, Switch, Redirect } from "react-router-dom";
import { LoginPage, UserDetailsPage } from "pages";

const Router = () => (
  <Switch>
    <Redirect from="/" to="/layout1"/>
    <Route path="/layout1" component={LoginPage} />
    <Route path="/layout2" component={UserDetailsPage} />
  </Switch>
);

export default Router;
Enter fullscreen mode Exit fullscreen mode

Next step, Create two different layout files(DashboardLayout.js, LoginLayoutRoute.js ) and their respective routes to implement multiple layouts.

LoginLayoutRoute.js

import React from 'react';  
import { Route } from 'react-router-dom';  

const LoginLayout = ({ children }) => (                         
    <div>  
      {children}                                       
    </div>  
  );  

  const LoginLayoutRoute = ({component: Component, ...rest}) => {  
    return (  
      <Route {...rest} render={props => (  
        <LoginLayout>  
            <Component {...props} />  
        </LoginLayout>  
      )} />  
    )  
  };  

export default LoginLayoutRoute;  
Enter fullscreen mode Exit fullscreen mode

DashboardLayout.js

import { Route } from 'react-router-dom';

const DashboardLayout = ({ children, ...rest }) => {
  return (
    <div className='page page-dashboard'>
      <header>
        <h1>Dashboard</h1>
        <p>The agent dashboard has 3 parts, a side menu, a top bar and content area to render components.</p>
      </header>
      <section>
        <nav>
          <p>
            DashboardLayout.js contains a higher order component (HOC) that
            takes a component as a prop and passes it into a `Route` from
            react-router-dom.
          </p>
          <p>
            The specific path for the component being passed to the HOC is
            passed to the Route in the spread ...rest .
          </p>
        </nav>
        <article>{children}</article>
      </section>
      <footer>
        <p>Footer</p>
      </footer>
    </div>
  );
};

const DashboardLayoutRoute = ({ component: Component, ...rest }) => {
  return (
    <Route
      {...rest}
      render={(props) => (
        <DashboardLayout>
          <Component {...props} />
        </DashboardLayout>
      )}
    />
  );
};

export default DashboardLayoutRoute;

Enter fullscreen mode Exit fullscreen mode

Both Login & Dashboard Layout contains a higher-order component (HOC) that takes a component as a prop and passes it into a Route from react-router-dom. The specific path for the component being passed to the HOC is passed to the Route in the spread ...rest.

A child component will be rendered at {children} and the rest of the elements will remain the same for all the child components that are using this layout.

As we can see here, by changing the route, different master pages are rendered for different components in DOM.

Layout 1:
Alt Text
Layout 2:
Alt Text

The finished code can be found on github.

Happy coding!

Top comments (5)

Collapse
 
shakhawatfci profile image
shakhawat hossain sabbir

freaking wired while vue multi layouting is so simple

Collapse
 
mai301 profile image
Mai-301

Can you please help where should i add those layout routes at the app architecture? i mean at the pages folder or components for instance?
i believe it should not be neither page nor components .

Appreciate your help.

Collapse
 
watzon profile image
Chris Watson

You can put them anywhere. In most cases with MVC you'd have a views directory with a layouts directory inside of it, but it's really up to you.

Collapse
 
dinesh0191 profile image
dinesh0191

hey what if I like to create a child route inside the dashboard

Collapse
 
selvaece25 profile image
Selva kumar

The Root component will be responsible for rendering all Layouts. Each Layout in turn will then be responsible for all the components using it.

Child route or nested route will have a new layout and pass it to Dashboard layout as props in addition will work as per expectation.