尝试自己写了下react项目的嵌套路由,但是感觉还不是特别的完美,如果代码有什么问题,或者有更好的方案,欢迎探讨指正。
这是我的react和react-router-dom的版本:
"react": "^17.0.2",
"react-router-dom": "^5.2.0",
下面是代码实现
App.tsx
import React, { Suspense } from "react";
import { BrowserRouter, Redirect, Route, Switch } from "react-router-dom";
import { routes, IRouteItem } from "@/routes";
function App() {
const renderRoutes = (data: IRouteItem[]) => {
if (data && data.length > 0) {
return data.map(
({ component: Component, path, routes, exact, redirect }) => {
return routes && routes.length > 0 ? (
<Route
key={path}
path={path}
render={(props) => (
<Component {...props}>
{redirect ? (
<Route
exact={exact}
path={path}
render={() => <Redirect to={redirect} />}
/>
) : (
<Route
exact={exact}
path={path}
render={() => <Redirect to={routes[0].path} />}
/>
)}
{renderRoutes(routes)}
</Component>
)}
/>
) : redirect ? (
<Route
key={path}
path={path}
exact={exact}
render={() => <Redirect to={redirect} />}
/>
) : (
<Route
key={path}
path={path}
exact={exact}
render={(props) => <Component {...props} />}
/>
);
}
);
}
};
return (
<BrowserRouter>
<Suspense fallback={null}>
<Switch>
{renderRoutes(routes)}
</Switch>
</Suspense>
</BrowserRouter>
);
}
export default App;
routes/index.ts
import { lazy } from "react";
export interface IRouteItem {
path: string;
redirect?: string;
component?: any;
exact?: boolean;
routes?: IRouteItem[];
}
export const routes: IRouteItem[] = [
{
path: "/",
redirect: "/a",
exact: true,
},
{
path: "/a",
exact: true,
// redirect: "/a/accountcenter",
component: lazy(() => import("@/pages/Index")),
routes: [
{
path: "/a/tasklist",
exact: true,
component: lazy(() => import("@/pages/TaskList")),
},
{
path: "/a/accountcenter",
exact: true,
component: lazy(() => import("@/pages/AccountCenter")),
},
],
},
{
path: "/demo",
exact: true,
component: lazy(() => import("@/pages/Demo")),
},
{
path: "*",
exact: true,
component: lazy(() => import("@/pages/NotFound")),
},
];