Home > Software design >  Can you map a a list of routes for React?
Can you map a a list of routes for React?

Time:12-31

So, I want to create a list of items, just as one would map a bunch of li elements into a given ul, but instead, to do the same with routes, however, how can I represent the name of the route element component into the element property, i.e. how could I represent this:

const navTitlesArray = [
  "routeComponent1",
  "routeComponent2",
  "routeComponent3",
  ...
]

const navRoutes = navTitlesArray.map(routeTitle => 
  <Route
    key={`${routeTitle}`}
    path={`/${routeTitle}`}
    element={<{routeTitle}/>}
  ></Route>
)

Specifically pointing towards the element property, assuming that my array holds the strings of the same titles as my route components, but right now it will not work as the routeTitle = string

CURRENTLY, as a solution, I did find the option to create a second array, with my components (given that I have imported them...) and use a loop to give the element prop a value from the 2nd array ( the array of the components), as such:

const navTitlesArray = [
  "routeComponent1",
  "routeComponent2",
  "routeComponent3",
  ...
]

const navComponentsArray = [
  <RouteComponent1 />,
  <RouteComponent2 />,
  <RouteComponent3 />,
  ...
]

for (let i = 0; i < navTitlesArray.length; i  ) {
  let route = <Route
    key={`${navTitlesArray[i]}`}
    path={`/${navTitlesArray[i]}`}
    element={navComponentsArray[i]}
  ></Route>
  navRoutes.push(route)

This DOES work, but I feel like if there is an option to implement the code as shown first, it would be a lot more efficient.

CodePudding user response:

replace your string array with jsx elements objects

const navTitlesArray = [{path: 'routeComponent1' , component: <routeComponent1/>},...]

const navRoutes = navTitlesArray.map( routeTitle => <Route key={`${routeTitle.path}`} path={`/${routeTitle.path}`} element={routeTitle.component}></Route>)

CodePudding user response:

It seems you are specifying one array to be the path/title you want to render a component on while the other array is the component/JSX you want to render. If you want to do it the first way with an array of string names and dynamically load the routed component then you'll still need to import the component and create a component "lookup" mapping.

Example:

import { Route } from 'react-router-dom';
import {
  RouteComponent1,
  RouteComponent2,
  RouteComponent3,
  ...etc...
} from '../components';

const components = {
  routeComponent1: RouteComponent1,
  routeComponent2: RouteComponent2,
  routeComponent3: RouteComponent3,
  ...etc...
};

const navTitlesArray = [
  "routeComponent1",
  "routeComponent2",
  "routeComponent3",
  ...etc...
];

const navRoutes = navTitlesArray
  filter(title => components[title])
  .map(title => {
    const Component = components[title];
    return (
      <Route
        key={title}
        path={`/${title}`}
        element={<Component />}
      />
    );
  });

It would be a bit more efficient to create the array with the path and element as a RouteObject and map it directly.

Example:

import { Route } from 'react-router-dom';
import {
  RouteComponent1,
  RouteComponent2,
  RouteComponent3,
  ...etc...
} from '../components';

const appRoutes = [
  {
    path: "/routeComponent1",
    element: <RouteComponent1 />,
  },
  {
    path: "/routeComponent2",
    element: <RouteComponent2 />,
  },
  {
    path: "/routeComponent3",
    element: <RouteComponent3 />,
  },
  ...etc...
];

const navRoutes = appRoutes.map(route => <Route key={route.path} {...route} />);

It should be noted that at this point you are sort of reinventing the wheel with regards to a "routes config". You could just specify the routes you want to render as a RouteObject array and use the useRoutes hook.

Example:

import { useRoutes } from 'react-router-dom';
import {
  RouteComponent1,
  RouteComponent2,
  RouteComponent3,
  ...etc...
} from '../components';

const appRoutes = [
  {
    path: "/routeComponent1",
    element: <RouteComponent1 />,
  },
  {
    path: "/routeComponent2",
    element: <RouteComponent2 />,
  },
  {
    path: "/routeComponent3",
    element: <RouteComponent3 />,
  },
  ...etc...
];

const App = () => {
  const routes = useRoutes(appRoutes);

  return routes;
};
  • Related