使用路由器配置对路由器v5进行反应:重定向到subroute



我有一个应用程序,它在边栏上有所有主页(仪表板、报告等(。主页可以包含一个带有导航链接的TopBar。据我所知,如果用户点击一条带有子路线的路线,它只会呈现顶栏:他必须再次点击子路线。我想自动呈现第一个子例程。我该怎么做?

const routes = [
{
label: "Dashboard",
path: "/dashboard",
component: DashboardComponent,
},
{ 
label: "Reporting",
path: "/reporting",
component: ReportSelection,
},
{
label: "Sales Data",
subLabel: "All tracked sales, leads and booked calls",
path: "/sales-data",
routes: [
{
label: "Sales",
path: "/sales-data/sales",
component: () => <SalesComponent calls={false}/>,
},
{
label: "Leads",
path: "/sales-data/leads",
component: LeadsComponent,
},
{
label: "Calls",
path: "/sales-data/calls",
component: () => <SalesComponent calls={true}/>,
},
{
label: "Phone closing",
path: "/sales-data/phone-closing",
component: PhoneClosingComponent,
}
]
},
]

function RouteWithSubRoutes(route) {
return (
<Route
path={route.path}
render={props => {
return (
// pass the sub-routes down to keep nesting
route.routes?.length > 0 ? 
<SubPage {...props} route={route} /> :
<route.component {...props} routes={route.routes} />
)}}
/>
);
}
/**
* You may have some routes with child routes, such as "sales-data" route which has four subroutes. In that case, use SubPage component to render a Navbar to the top with links to subroutes.
* @param route The route with subroutes. 
* @returns 
*/
function SubPage({ route }) {
console.log(route);
return (
<div>
<HPageHeader title={route.label} subtitle={route.subLabel}>
{route.routes.map((route, _idx) => (
<NavLink to={route.path}>{route.label}</NavLink>
))}
</HPageHeader>

<Switch>
{route.routes.map((route, i) => (
<RouteWithSubRoutes key={i} {...route} />
))}
</Switch>
</div>
);
}
/**
* This component is the root of the application. It contains :
* - The router
* - The topbar 
* - The Sidebar, which contain Links to the first nodes of the app.
* - The switch, who manage the component to render according to the route.
*/
export const App: React.FC = () => {
const [collapsed, setCollapsed] = React.useState<boolean>(false);
return (
<HashRouter basename="/mh">
<TopbarComponent
onToggleCollapse={() => setCollapsed(collapsed => !collapsed)}
></TopbarComponent>
<SidebarComponent routes={routes} collapsed={collapsed}/>
<Switch>
<div style={{marginLeft: collapsed ? "64px" : "220px"}}>
{routes.map((route, idx) => (
<RouteWithSubRoutes key={idx} {...route}/>
))}
</div>
</Switch>
</HashRouter>
)
}

根据您的描述,听起来您想要一个类似于索引路由的准等价路径,也就是说,当URL路径与父路径而不是嵌套的子路径匹配时,呈现组件。react-router-domv5Route组件可以采用一组路径。指定父路径以及第一个子管线的路径。

示例:

const routes = [
{
label: "Dashboard",
path: "/dashboard",
component: DashboardComponent,
},
{ 
label: "Reporting",
path: "/reporting",
component: ReportSelection,
},
{
label: "Sales Data",
subLabel: "All tracked sales, leads and booked calls",
path: "/sales-data",
routes: [
{
label: "Sales",
path: ["/sales-data/sales", "/sales-data"],
component: () => <SalesComponent calls={false} />,
},
{
label: "Leads",
path: "/sales-data/leads",
component: LeadsComponent,
},
{
label: "Calls",
path: "/sales-data/calls",
component: () => <SalesComponent calls={true} />,
},
{
label: "Phone closing",
path: "/sales-data/phone-closing",
component: PhoneClosingComponent,
}
]
},
]

如果路由路径和Switch组件有任何冲突,您可能希望在Route组件上使用exact道具。

只是说我解决了它(使用v5,v6使用Outlet组件,使事情变得更容易(,如下所示:

const RouteConfigRenderer = (props: Props) => {
const createTree = (route: RouteDefintion) => {
// It's a main route (a leaf in the route.config tree), or it's a route with child routes
if (route.component) {
// Route with child routes
if (route.routes?.length > 0) {
return (
<Route path={route.path}>
<route.component {...route as any} ></route.component>
<div style={{overflow: "scroll", height: "calc(100vh - 188px)"}}>
<Switch>
{route.routes?.map(r => createTree(r))}
<Redirect  to={`${RouterUtils.getRedirect(route.routes).path}`}/>
</Switch>
</div>
</Route>
)
} else { // It's a main route (a leaf in the route.config tree)
return <Route path={route.path}>
<route.component {...route as any} ></route.component>
</Route>
}
} else { // It's a index route
return (
<Route path={route.path}>
<Switch >
{route.routes?.map(r => createTree(r))}
<Redirect to={`${RouterUtils.getRedirect(route.routes).path}`}/>
</Switch>
</Route>
)
}
}

return (
<Switch>
{props.routes.map(r => createTree(r))}
<Redirect to={`${RouterUtils.getFirstRedirect().path}`}/>
</Switch>
)
}

RouteConfig看起来像这个

const routes = [{
path: "/reporting",
routes: [
{
path: "/reporting/:type",
component: () => <ReportComponent/>
},
{
path: "/reporting",
component: ReportSelection
},
]
},
{
path: "/sales-data",
component: IndexNavBarComponent,
routes: [
{
path: "/sales-data/sales",
component: () => <SalesComponent calls={false}/>,
},
{
path: "/sales-data/leads",
component: LeadsComponent,
},
{
path: "/sales-data/calls",
component: () => <SalesComponent calls={true}/>,
},
{
path: "/sales-data/phone-closing",
component: PhoneClosingComponent,
}
]
}
]

最新更新