Search code examples
reactjsreact-router-dom

React Router Dom v6 with Typescript


I have upgraded to react-router-dom v6 I have been using RouteComponentProps for mapping over routes as below but was wondering how to inplement this in v6

<Switch>
        {routes.map((route, index) => {
            return (
                <Route
                    key={index}
                    exact={route.exact}
                    path={route.path}
                    render={(routeProps: RouteComponentProps<any>) => (
                        <route.component {...routeProps} />
                    )}
                />
            );
        })}
    </Switch>

I know that Switch is now replaced with Routes, but tnot sure what replaces RouteComponentProps


Solution

  • react-router-dom 6.4 recommends using createBrowserRouter for web apps. It uses the DOM History API to update the URL and manage the history stack.

    const App = () => {
    
    
      const routes = [
        {
          path: "/",
          element: <Dashboard />,
        },
        {
          path: "/messages",
          element: <Messages />,
        },
         {
          path: "/messages/:slug",
          element: <Message />,
        }
      ];
    
      return <RouterProvider router={createBrowserRouter(routes)} />
    };
    

    Each route can define a loader function that provides data through useLoaderData to the root element before rendering.

    const AppRoutes = () => {
    
    
      const routes = [
        {
          path: "/",
          element: <Dashboard />,
          loader: async () => {
             return fetch(`/api/dashoard`);
          },
        },
        {
          path: "/messages",
          element: <Messages />,
          loader: async () => {
              return fetch(`/api/messages`);
          },
        },
         {
          path: "/messages/:slug",
          element: <Message />,
          loader: async ({param}) => {
              return fetch(`/api/messages/${param.slug}`);
          },
        }
      ];
    
      return <RouterProvider router={createBrowserRouter(routes)} />
    };
    
    const Message = () => {
      const data = useLoaderData()
      return <p> {data.message} </p>
    
    }
    
    

    You probably need to use <Suspanse> too. It is a built-in react component.

        <Suspense>
          <RouterProvider router={createBrowserRouter(routes, { basename })} />
        </Suspense>
    

    References

    1. https://reactrouter.com/en/main/routers/create-browser-router

    2. https://reactrouter.com/en/main/route/loader

    3. https://reactrouter.com/en/main/hooks/use-loader-data


    Original answer

    Version 6 does not have Switch and has removed the render function too.

    Instead of Switch, use Routes.

    Intead of the render method, use element which is a React.ReactNode .

    <Routes>
      <Route path="/" element={<Dashboard />} />
      <Route path="messages" element={<DashboardMessages />} />
      <Route path="tasks" element={<DashboardTasks />} />
      <Route path="about" element={<AboutPage />} />
    </Routes>;
    

    Only if <route.component /> is a React.ReacNode.

    <Routes>
      {routes.map((route, index) => {
        return (
          <Route key={index} path={route.path} element={<route.component />} />
        );
      })}
    </Routes>;
    
    

    Reference:

    https://reactrouter.com/docs/en/v6/components/route