Search code examples
reactjsmaterial-uireact-router-dom

How does this Codesandbox Reactjs app MainLayout work


I learn React and read lots of code and now I see this Codesandbox and cant understand why there are two Main Layout both with a ToolBar

Basically it looks like this:

Routs:

const routes = [
  {
    path: 'app',
    element: <DashboardLayout />,
    children: [
      { path: 'account', element: <AccountView /> },
      { path: 'customers', element: <CustomerListView /> },
      { path: 'dashboard', element: <DashboardView /> },
      { path: 'products', element: <ProductListView /> },
      { path: 'settings', element: <SettingsView /> },
      { path: '*', element: <Navigate to="/404" /> }
    ]
  },
  {
    path: '/',
    element: <MainLayout />,
    children: [
      { path: 'login', element: <LoginView /> },
      { path: 'register', element: <RegisterView /> },
      { path: '404', element: <NotFoundView /> },
      { path: '/', element: <Navigate to="/app/dashboard" /> },
      { path: '*', element: <Navigate to="/404" /> }
    ]
  }
];

export default routes;

There you have the DashboardLayout and MainLayout and when app start I see that MainLayout is rendered first and the default rout is <Navigate to="/app/dashboard" /> and that is the DashboardLayout.

When looking in the code for MainLayout I see a mirroring of code same as in DashboardLayout:

Like MainLayout:

const useStyles = makeStyles((theme) => ({
  root: {
    backgroundColor: theme.palette.background.default,
    display: 'flex',
    height: '100%',
    overflow: 'hidden',
    width: '100%'
  },
  wrapper: {
    display: 'flex',
    flex: '1 1 auto',
    overflow: 'hidden',
    paddingTop: 64
  },
  contentContainer: {
    display: 'flex',
    flex: '1 1 auto',
    overflow: 'hidden'
  },
  content: {
    flex: '1 1 auto',
    height: '100%',
    overflow: 'auto'
  }
}));

const MainLayout = () => {
  const classes = useStyles();

  return (
    <div className={classes.root}>
      <TopBar />
      <div className={classes.wrapper}>
        <div className={classes.contentContainer}>
          <div className={classes.content}>
            <Outlet />
          </div>
        </div>
      </div>
    </div>
  );
};

export default MainLayout;

Like DashboardLayout:

const useStyles = makeStyles((theme) => ({
  root: {
    backgroundColor: theme.palette.background.dark,
    display: 'flex',
    height: '100%',
    overflow: 'hidden',
    width: '100%'
  },
  wrapper: {
    display: 'flex',
    flex: '1 1 auto',
    overflow: 'hidden',
    paddingTop: 64,
    [theme.breakpoints.up('lg')]: {
      paddingLeft: 256
    }
  },
  contentContainer: {
    display: 'flex',
    flex: '1 1 auto',
    overflow: 'hidden'
  },
  content: {
    flex: '1 1 auto',
    height: '100%',
    overflow: 'auto'
  }
}));

const DashboardLayout = () => {
  const classes = useStyles();
  const [isMobileNavOpen, setMobileNavOpen] = useState(false);

  return (
    <div className={classes.root}>
      <TopBar onMobileNavOpen={() => setMobileNavOpen(true)} />
      <NavBar
        onMobileClose={() => setMobileNavOpen(false)}
        openMobile={isMobileNavOpen}
      />
      <div className={classes.wrapper}>
        <div className={classes.contentContainer}>
          <div className={classes.content}>
            <Outlet />
          </div>
        </div>
      </div>
    </div>
  );
};

export default DashboardLayout;

What is the benefits of doing it like this I mean the MainLayout is rendered for what reason? Does this have to do with the useRoutes elements structure like grouping rout element?


Solution

  • This is a common pattern in template layouts and is good design practice in general. The primary reason it is used is for authenticated/unauthenticated routes (i.e logged in vs not logged in). You will notice the topbar.js for both layouts is quite different.

    For the Main layout, this is your unauthenticated layout, it is the place where you may show the home page, about page etc. which you want accessible by anyone. With this, you probably don't want to show usual nav items such as a profile link etc. You can of course do this using state in React but it is much tidier to do it the latter way and you don't have to have other potentially complex code running while not authenticated under the app path.

    The Dashboard layout is what would typically be used as an authenticated path. This may be a company's back end admin section or other web app.

    Templates like this often provide just enough separation like this so that developers can implement their own auth & backend capabilities into the app but can still see an intended design path for all of the components which have been created.