'Config route in react-router-dom v6

I am using react-router-dom with typescript. I create a config file like below:

export interface RouteComponent {
  path?: string;
  element?: React.ComponentType<any>;
  children?: RouteComponent[];
}

const routes: RouteComponent[] = [
  {
    element: MenuLayout,
    children: [
      {
        path: "corp-list",
        element: CorpList,
      },
      {
        path: "/corp-list/:id",
        element: DetailCorp,
      },
    ],
  },
  {
    children: [
      {
        path: "auth/login",
        element: Login,
      },
      {
        path: "auth/signup",
        element: Login,
      },
    ],
  },
]; 

Then, I map it to render routes in App.tsx file

{routes.map((route, index) => (
        <Route
          path={route.path as string}
          element={route.element}
        />
      ))}

It shows an error of type which the element in Route component take children with type of ReactNode, not the React.Component as above. But when I try to declare element in config routes with type of ReactNode, like :

{ path: "corp-list", element: <CorpList /> },

it yells "CorpList refers to a value, but is being used as a type here".

So, how to fix that? And, how do you config route in react-router-dom v6, any suggestion? Thank you in advance!



Solution 1:[1]

If you are creating a routes config then use the type react-router-dom exports, RouteObject in this case.

RouteObject

/**
 * A route object represents a logical route, with (optionally) its child
 * routes organized in a tree-like structure.
 */
export interface RouteObject {
  caseSensitive?: boolean;
  children?: RouteObject[];
  element?: React.ReactNode;
  index?: boolean;
  path?: string;
}

Key differences from your type declaration is that element is a React.ReactNode and the children is an array of RouteObject.

Import RouteObject and in your config pass the element values as JSX.

import { RouteObject } from "react-router-dom";

const routesConfig: RouteObject[] = [
  {
    element: <MenuLayout />,
    children: [
      {
        path: "corp-list",
        element: <CorpList />
      },
      {
        path: "corp-list/:id",
        element: <DetailCorp />
      }
    ]
  },
  {
    children: [
      {
        path: "auth/login",
        element: <Login />
      },
      {
        path: "auth/signup",
        element: <Login />
      }
    ]
  }
];

Don't reinvent the wheel, react-router-dom exports a hook to consume the routes config object and returns the matched element or null.

useRoutes

The useRoutes hook is the functional equivalent of <Routes>, but it uses JavaScript objects instead of <Route> elements to define your routes. These objects have the same properties as normal <Route> elements, but they don't require JSX.

The return value of useRoutes is either a valid React element you can use to render the route tree, or null if nothing matched.

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

...

const routes = useRoutes(routesConfig);

return (
  ... nav bar ...
  {routes}
  ...
);

Edit config-route-in-react-router-dom-v6

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Drew Reese