React Router 嵌套 children?

React Router with nested children?

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

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

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

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

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

如果我正确理解了你想要实现的目标,你可以在你的路由器中做这样的事情:

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

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

我会这样想象你的路线树:

/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')))
  }
}