簡體   English   中英

將 React 路由組織成單獨的組件

[英]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>
    )
}

更新#1

這要感謝@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不是RouteSwitch無論如何都會查看它的props.path 一旦undefined for props.path匹配任何路徑並且Switch只呈現第一個匹配的Route ,您只會得到第一個呈現的組件。

[UPD] "does-not-match-any-route" 視圖僅適用於Switch的頂層。 也沒有辦法知道兄弟元素的一些嵌套子元素是否與當前路由匹配。 所以我看到的唯一方法是在一個地方列出所有路線。

看起來相當糟糕的替代方案是具有特殊的路由“/error404”並將用戶從其他組件內部重定向到它(但誰應該決定?在哪里?何時?)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM