【问题标题】:React Router with nested children?带有嵌套子级的反应路由器?
【发布时间】:2016-08-11 23:24:08
【问题描述】:

查看 react-router github 上的 huge-apps 示例,我不确定如何设置我想要的路由。

URL        | Result
--------------------------
/sites     | List of sites
/sites/:id | One site

如果我想列出多个站点,站点组件/路由需要嵌套在站点组件/路由中。因此,我的文件夹结构看起来类似于 react-router 示例中的分配模型。

/routes
    /Sites
        /components
        |   Sites.js
        /routes
        |   /Site
        |   |   /components
        |   |   |   Site.js
        |   |   index.js
        index.js

但是,对于/sites/:id 路由,它不依赖于站点组件。我会在 Sites 目录的同一级别上创建另一个 Site 目录,还是让 Site 组件能够呈现列表和单一视图?我的 index.js 文件会是什么样子?

【问题讨论】:

    标签: javascript reactjs react-router


    【解决方案1】:

    我会以这种方式可视化您的路线树:

    /sites
    (Sites.js)
    - /:id1
      (Site1.js)
    - /:id2
      (Site2.js)
    

    在您的 index.js 中,类似这样的内容(使用客户端示例):

    render((
      <Router history={browserHistory}>
        <Route path="/" component={App}>
          <IndexRoute component={Home} />
          <Route path="/sites" component={Sites}>
            <Route path="/sites/:id" component={Site}/>
          </Route>
        </Route>
      </Router>
    ), document.getElementById('app'));
    

    每条路线都有一个附带的组件。你可以在这些组件中添加任何你想要的东西,尽管包含一些导航到子路由的方法可能会有所帮助。

    PlainRoute 版本(虽然我不确定你为什么想要):

    const rootRoute = {
      component: 'div',
      childRoutes: [{
        path: '/',
        component: require('./components/App'),
        childRoutes: [ require('./routes/Sites') ]
      }]
    }
    
    render(
      <Router history={browserHistory} routes={rootRoute} />,
      document.getElementById('example')
    );
    

    './routes/Sites':

    module.exports = {
      path: 'sites',
      getChildRoutes(location, cb) {
        require.ensure([], (require) => cb(null, [ require('./routes/Site') ]))
      },
      getComponent(nextState, cb) {
        require.ensure([], (require) => cb(null, require('./components/Sites')))
      }
    }
    

    './routes/Site':

    module.exports = {
      path: 'sites/:id',
      getComponent(nextState, cb) {
        require.ensure([], (require) => cb(null, require('./components/Site')))
      }
    }
    

    【讨论】:

    • 你会如何用 PlainRoutes 来做这件事,这个例子是怎么做的?
    • 我不知道当 JSX 在可读性方面更高效时,你为什么要使用 PlainRoutes。根据示例中使用的文件结构,我将在原始答案中附加我对 PlainRoutes 版本的最佳尝试。
    • 如您所见here,代码拆分更好。无论如何,提前谢谢。
    • 感谢您更新答案。最后一个问题,对于 JSX 路由,您在路径前放置一个反斜杠,但对于普通路由则没有。反斜杠是否从父路由附加?如果是这样,是否应该将 sites/:id 更改为 :id
    • 你可能是对的。我需要做一些测试来验证;我目前不能这样做。我自己在我的 JSX 路由中总是将路径写为绝对路径,在这种情况下,每个路径前面都应该有一个 /。
    【解决方案2】:

    如果我正确理解您想要实现的目标,您可以在路由器中执行以下操作:

    <Route path="/sites/:id" component={SingleSite} />
    <Route path="/sites" component={Sites} />
    

    SingleSite 组件采用 id 参数并使用它来显示站点。如果有 ID,React 路由器应该能够使用 SingleSite 组件,如果没有 ID,则显示 Sites 组件。

    【讨论】:

    • 在 Sites 组件映射/创建每个 Site 时,您能否将 prop 传递给 Site 组件?
    • 我想这取决于您是否希望 Site 组件显示为 Sites 组件的子组件。我认为,因为您不想同时显示列表和单个站点,所以最好将它们作为具有所有站点对象的父级下的兄弟姐妹。 Sites 将遍历该对象并显示所有内容,Site 将在 react 路由器的 params prop 中接收 :id,然后过滤从父级传递下来的 prop。
    • 这是有道理的。我想将两者都放在一个组件中使它更像是 MVC 中的模型而不是组件。有必要把更深的路径放在第一位吗?例如,将/sites/:id 放在/sites 路由之后会导致/sites/:id 永远不会被渲染吗?
    猜你喜欢
    • 2017-07-23
    • 2017-05-19
    • 2020-09-23
    • 2019-02-18
    • 2019-01-12
    • 1970-01-01
    • 1970-01-01
    • 2016-08-18
    • 1970-01-01
    相关资源
    最近更新 更多