繁体   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