[英]Organizing React routes into separate components
我正在嘗試找到一種方法來組織我的路線,以幫助將來可能接管我工作的開發人員。 我想將我的<Route />
條目分成單獨的組件,然后將它們加載到類似於用戶分配組的主要組件中。
問題是,當使用多個組件時,只有第一個組件有效。 這可能不是最有效的方式,所以我也願意接受替代方案。
原路線安排
const AllRoutes = () => {
return (
<Switch>
{/* public routes*/}
<Route path={'/about'} component={AboutView} />
<Route path={'/project'} component={ProjectView} />
<Route path={'/contact'} component={ContactView} />
{/* auth routes */}
<Route path={'/login'} component={LoginView} />
<Route path={'/logout'} component={LogoutView} />
<Route component={Error404View} />
</Switch>
)
}
將公共路由與認證路由分開:
const PublicRouteGroup = () => {
return (
<>
<Route path={'/about'} component={AboutView} />
<Route path={'/project'} component={ProjectView} />
<Route path={'/contact'} component={ContactView} />
</>
)
}
const AuthRouteGroup = () => {
return (
<>
<Route path={'/login'} component={LoginView} />
<Route path={'/logout'} component={LogoutView} />
</>
)
}
這樣我就可以這樣使用它:
const AllRoutes = () => {
return (
<Switch>
<PublicRouteGroup /> {/* This works */}
<AuthRouteGroup /> {/* This doesn't */}
{/* This 404 is not a route group */}
<Route component={Error404View} />
</Switch>
)
}
翻轉<PublicRouteGroup />
和<AuthRouteGroup />
只會改變順序:
const AllRoutes = () => {
return (
<Switch>
<AuthRouteGroup /> {/* This works */}
<PublicRouteGroup /> {/* This doesn't */}
{/* This 404 is not a route group */}
<Route component={Error404View} />
</Switch>
)
}
這要感謝@skyboyer。 通過將<Switch>
移動到子組件並將其從每個組件開始顯示的AllRoutes
組件中刪除。 似乎在AllRoutes
中添加<Switch>
只允許第一個命中顯示與<Switch>
一樣。 但是現在通過刪除它,它也會在每頁的末尾顯示 404。
基本上,它看起來像這樣:
const AllRoutes = () => {
return (
<>
<Route component={AuthRouteGroup} /> {/* This works */}
<Route component={PublicRouteGroup} /> {/* This also works */}
{/* This 404 is not a route group */}
<Route component={Error404View} /> {/* Always shown at the bottom */}
{/* Even putting the 404 in its own RouteGroup yields the same issue */}
</>
)
}
看來,當前處理組件(如您可以擴展的 OOP 類)的設置是錯誤的方法。 我改用了 arrays 因為這些可以由擴展運算符執行。 它仍然實現了在無限數量的組中組織路線的相同目標,這正是我所追求的。
為每個組創建數組
const public_route_group = [
{path: '/about', component: AboutView},
{path: '/project', component: ProjectView},
{path: '/contact', component: ContactView},
]
const auth_route_group = [
{path: '/login', component: LoginView},
{path: '/logout', component: LogoutView},
]
const error_route_group = [
{component: Error404View} // No path required
]
const user_routes = [
...public_route_group,
...auth_route_group,
...error_route_group
]
創建路線
const AllRoutes = () => {
return (
<Switch>
{user_routes.map((route, idx) => {
return <Route key={idx} {...route} />
})}
</Switch>
)
}
如果您在數組中使用嵌套對象,我認為這也可以進一步修改。
我要感謝@skyboyer 提供了對這個問題的見解。
沒有頂級的Swtich
怎么樣
<Route component={PublicRouteGroup} />
<Route component={AuthRouteGroup} />
所以它們被無條件地渲染。 然后在您的組件中添加額外的Switch
,例如
const AuthRouteGroup = () => {
return (
<Switch>
<Route path={'/login'} component={LoginView} />
<Route path={'/logout'} component={LogoutView} />
<Switch/>
)
}
但為什么 id 不起作用?
原因是Switch
的工作原理:
React.Children.forEach(this.props.children, child => {
if (match == null && React.isValidElement(child)) {
element = child;
const path = child.props.path || child.props.from;
match = path
? matchPath(location.pathname, { ...child.props, path })
: context.match;
}
});
看,即使AuthRouteGroup
不是Route
, Switch
無論如何都會查看它的props.path
。 一旦undefined
for props.path
匹配任何路徑並且Switch
只呈現第一個匹配的Route
,您只會得到第一個呈現的組件。
[UPD] "does-not-match-any-route" 視圖僅適用於Switch
的頂層。 也沒有辦法知道兄弟元素的一些嵌套子元素是否與當前路由匹配。 所以我看到的唯一方法是在一個地方列出所有路線。
看起來相當糟糕的替代方案是具有特殊的路由“/error404”並將用戶從其他組件內部重定向到它(但誰應該決定?在哪里?何時?)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.