【问题标题】:React router best practices for nested navigation?嵌套导航的反应路由器最佳实践?
【发布时间】:2016-11-30 19:49:12
【问题描述】:

我正在构建一个 React 应用程序,并使用 React Router 来管理路由。应用的信息架构可以表示如下:

 - App
     - Projects
         - Project 1
             - Objects
               - Object 1
               - Object 2
               - etc...
             - Collaborators
         - ...
     - Services
     - Users

当查看/#/projects/1/components/1这样的路由时,应用程序的用户界面看起来像这样

-----------------------------------------------------------
|            | Home > Projects > 0 > Object > 1           |
|  Home      |--------------------------------------------|
|            |                                            |
|  Projects  |   Object 1                                 |
|            |                                            |
|  Services  |   Blah blah blah                           |
|            |                                            |
|  Users     |                                            |
|            |                                            |
-----------------------------------------------------------

请注意,对于上述信息架构方案中显示的任何给定路由,视图应呈现在主体部分(上图中呈现“组件 1”)。

现在我将描述我是如何使用 React Router 在 React 中错误地实现这一点的:

我一直在使用 PlainRoutes 来定义我的路线。下面是一个如何定义路由的简短示例:

const routes = [
    {
        path: '/',
        component: App,
        name: 'Home',
        childRoutes: [
          // /projects
          {
              path: 'projects',
              component: Projects,
              name: 'Projects'
          },
          {
              path: 'projects/:projectid',
              component: ProjectDetails,
              name: 'Project Details',
              childRoutes: [
                  {
                       path: 'objects',
                       component: Objects,
                       name: 'Objects'
                  },
                  {
                      path: 'objects/:objectid',
                      component: ObjectDetails,
                      name: 'Object Details'
                  },
                  {
                      path: 'collaborators',
                      component: Collaborators,
                      name: 'Collaborators'
                  }
              ]
          },
          // /services
          {
              path: 'services',
              component: Services,
              name: 'Services'
          },
          // /users
          {
              path: 'users',
              component: Users,
              name: 'Users'
          }
      ]
   }
];

然后输入到 React Router 组件中,如下所示:<Router routes={routes}></Router>

做这种工作。当我尝试导航到:

/#/projects

我会看到应用程序主体中呈现的 Projects 组件。

当我尝试导航到:

/#/projects/1

我会看到在应用程序主体中呈现的 ProjectDetail 组件。

但是,当我尝试导航到:

/#/projects/1/objects

我仍然会看到在应用程序主体中呈现的 ProjectDetail 组件。我不确定为什么当/projects/:projectid 参数被解析时路由器会停止,而不是继续渲染分配给/projects/:projectid/objects 路由的组件。

我认为问题在于我以错误的方式使用 React Router。子路由应该在物理上嵌套在它们的父组件中 - 而不仅仅是逻辑嵌套。至少,我认为这是问题所在。显然,我对如何使用 React Router 感到有些困惑——尤其是 childRoutes 的概念。

那么问题是 - 如何使用 React Router 为应用程序提供我正在寻找的层次结构,如上所述?我希望路由器知道应用程序的深层嵌套结构(例如面包屑和导航),但我不想将组件物理嵌套在另一个内部。这里有哪些最佳做法?

【问题讨论】:

  • ProjectDetails 组件是否使用 this.props.children ?如果没有,Objects 组件将没有地方渲染。您希望它们同时出现在屏幕上还是只出现在屏幕上?
  • ProjectDetails 不使用this.props.children。我想渲染一个或另一个。因此,听起来对于层次结构的每个级别,我都需要创建一个空容器,并带有 indexRoute 来显示我们是否没有显示孩子。那是正确的方法吗?
  • 不,只是不要嵌套它们。我添加了一个答案,但想问你,你为什么在这里筑巢?只是为了分享一段字符串?
  • 我希望路由器跟踪活动路由,这样我就可以知道哪些路由是活动的,以及我在应用程序中的位置。我想知道的不仅仅是当前活动的路线——我还想知道当前的路径。我可以通过进行一些字符串解析从当前路由的路径中得出这一点,但我认为可能有更好的方法。

标签: reactjs react-router


【解决方案1】:

考虑到您不想在路径/#/projects/1/objects 上同时显示ProjectDetailsObjects,那么您不想嵌套这些路由。

childRoutes: [
      // /projects
      {
          path: 'projects',
          component: Projects,
          name: 'Projects'
      },
      {
          path: 'projects/:projectid',
          component: ProjectDetails,
          name: 'Project Details',
      },
      {
          path: 'projects/:projectid/objects',
          component: Objects,
          name: 'Objects'
      },
      {
          path: 'projects/:projectid/objects/:objectid',
          component: ObjectDetails,
          name: 'Object Details'
      },

只有当您打算将 Objects 填充到 this.props.childrenProjectDetails 中时,您才会嵌套路由。

【讨论】:

  • 正确 - 这似乎是另一种可行的方式。该方法的唯一问题是路由器似乎不了解信息层次结构。例如,如果我想构建一个面包屑路径,我会认为我想从routes 道具(从使用withRouterApp 组件传递下来)获取该信息。当我导航到/#/projects/1/objects/1routes 数组只包含两条​​路线:['Home','Object 1']。我希望它是 ['Home','Projects','Project 1','Objects','Object 1']
  • 嘿,抱歉,我没有就此事回复您。对于面包屑/活动路线,可能有一个聪明的解决方案,这对我来说并不明显而不是hacky(检查位置)。也许使用带有复数命名组件的嵌套路由而不是children
  • 不用担心 - 我想出了一个使用类似于您建议的解决方案的解决方案 - 尽管我不得不求助于解析当前路线的完整路径来构建面包屑和适当的导航元素。感谢您的帮助!
【解决方案2】:

您可以在项目详细信息组件中查看 this.props.children。你可以编写一个项目详细信息的渲染方法,如下所示

render(){
   this.props.children?this.props.children:<Project Details/>
}

这将检查子项是否可用,然后将呈现其子项,否则将呈现项目详细信息。

【讨论】:

    猜你喜欢
    • 2021-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-18
    • 1970-01-01
    • 1970-01-01
    • 2020-11-29
    • 1970-01-01
    相关资源
    最近更新 更多