DEV Community

Cover image for The right way to structure your react router

The right way to structure your react router

Kachi Cheong on July 18, 2022

React Router Tutorial People new to react generally don't know how to structure their routes. Beginners and entry level developers will...
Collapse
 
cwshields profile image
Chase Shields

What's the cleanest way to pass props into the route element in the pagesData.tsx file? This was the quick fix that VS Code applied, but it seems messy:

{
    path: "blog",
    element: <Blog id={0} title={""} description={""} tags={""} readTime={""} date={""} user={""} />,
    title: "Blog"
  },
Enter fullscreen mode Exit fullscreen mode
Collapse
 
kachiic profile image
Kachi Cheong

this will depend on the arguments of the *Blog *. If they are required I suggest:

const blogArgs = {
 title:"",
 description: "",
 tags="",
 readTime: "",
 date: ""
 user: ""
}

{
    path: "blog",
    element: <Blog {...blogArgs}/>,
    title: "Blog"
  },
Enter fullscreen mode Exit fullscreen mode
Collapse
 
cwshields profile image
Chase Shields

This is much better, thanks! What would you suggest for redirects with this method? Say, for example, if I want to redirect the path from the default "/", to "/home".

Thread Thread
 
lnguyen24794 profile image
Nguyễn Thành Lâm • Edited

You can do like this for less than v5 version
<Switch>
<Redirect exact from="/" to="/home"/>
</Switch>

Or for newest v6
<Route path="/" element={<Navigate to="/home" replace />} />

Collapse
 
joshlavely profile image
Josh Lavely

I really liked your article. Its a topic that needs to be talked about more.

Anyways my only thoughts were to make this lazy.

Then code-splitting can happen and we see big reductions in bundle sizes.

Collapse
 
songhee24 profile image
_/\ • Edited

you can do it like this

const pagesData: routerType[] = [
{
path: "",
element: React.lazy(() => import('./Home')),
title: "home"
},
{
path: "about",
element: React.lazy(() => import('./About')),
title: "about"
}
];

Collapse
 
benjaminsson profile image
Johan Benjaminsson

Interesting way to structure it!
One thing i didn't understand. You changed format from JSX to an array of objects when you moved everything out off app.tsx. Combining that with splitting the code up in multiple files; doesn't that make it harder to read?

Collapse
 
kachiic profile image
Kachi Cheong

Hey Johan,

so actually this is the better practice as when you begin to scale the code it makes it more readable, for example if you have 100 routes for your site you can then begin to separate them like so

*Basic pages *

const basicRoutes = [
  {
    path: "",
    element: <Home />,
    title: "home"
  },
  {
    path: "about",
    element: <About />,
    title: "about"
  }
]
Enter fullscreen mode Exit fullscreen mode

Advance Page

const advancedRoutes = [
  {
    path: "complex",
    element: <Complex />,
    title: "complex"
  },
  {
    path: "assignment",
    element: <Assignment />,
    title: "assignment"
  }
]
Enter fullscreen mode Exit fullscreen mode

All routes

export const allRoutes = [...basicRoutes,...advancedRoutes]
Enter fullscreen mode Exit fullscreen mode

Now actually the update to react router (which is now v6) makes this format moot. Their new structure is basically the same as the one i've suggested here instead of the JSX format. This makes it more readable when scaling.

Collapse
 
alexappelt profile image
alexappelt

Nice way to separate the routes in a single file and organizate it. .

Collapse
 
nilayjain0611 profile image
Nilay Jain

So we have created Types in this to use the routes, but how can we achieve it in javascript?

Collapse
 
paiatpeace profile image
Ameya Pai

But how do you handle nested routes?

Collapse
 
paiatpeace profile image
Ameya Pai • Edited

@kachiic You article helped me. This is how I used your solution for nested routes

router.jsx

import { Route, Routes } from 'react-router-dom';
import pages from '@/pages/pages';

const renderRoutes = (routes) => {
  return routes.map(({ path, title, element, children = [] }) => {
    return (
      <Route key={title} exact path={path} element={element}>
        {children.length > 0 && <Route>{renderRoutes(children)}</Route>}
      </Route>
    );
  });
};

const Router = () => {
  const pageRoutes = renderRoutes(pages);
  return <Routes>{pageRoutes}</Routes>;
};

export default Router;
Enter fullscreen mode Exit fullscreen mode

pages.jsx

const pagesData = [
  {
    path: '',
    element: <Landing />,
    title: 'landing',
  },
{
        path: 'work-experience',
        element: <WorkExperience />,
        title: 'workExperience',
        children: [
          {
            path: 'fresher',
            element: <Fresher />,
            title: 'fresher',
            children: [
              {
                path: 'education',
                element: <Education />,
                title: 'education',
              }]
 }].
}]

export default pagesData;
Enter fullscreen mode Exit fullscreen mode

This way I can achieve multi-level nested routing...