[英]react-router v5 with router-config: Redirect to 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-dom
v5 Route
組件可以采用一系列路徑。 指定父路徑以及第一個子路由的路徑。
例子:
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,
}
]
}
]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.