如何使用React Router嵌套路由

时间:2019-09-19 14:05:33

标签: javascript reactjs react-router react-router-dom

在将此问题标记为重复之前,请先阅读此问题。我有多个应包含不同屏幕的布局。每个布局都有其自己的页眉,页脚和类似页面应共享的其他内容。这是我想出的代码:

<BrowserRouter>
  <Route path={['/index', '/about']} component={BaseLayout}>
    <Route path="/index" component={Index} />
    <Route path="/about" component={About} />
  </Route>
  <Route path={['/sign-in', '/sign-up']} component={AuthLayout}>
    <Route path="/sign-in" component={SignIn} />
    <Route path="/sign-up" component={SignUp} />
  </Route>
  <Route path={['/stats'} component={DashboardLayout}>
    <Route path="/stats" component={Stats} />
  </Route>
</BrowserRouter>

上面的代码显然不起作用,因为:

  

警告:您不应该使用<Route component>和   相同的路线; <Route component>将被忽略

关于SO的类似问题的建议建议直接使用包装器组件:

<BrowserRouter>
  <BaseLayout>
    <Route path="/index" component={Index} />
    <Route path="/about" component={About} />
  </BaseLayout>
  <AuthLayout>
    <Route path="/sign-in" component={SignIn} />
    <Route path="/sign-up" component={SignUp} />
  </AuthLayout>
  <DashboardLayout>
    <Route path="/stats" component={Stats} />
  </DashboardLayout>
</BrowserRouter>

此方法的问题在于,即使它呈现单个屏幕,也呈现其他布局中的元素,即,如果您位于BaseLayout内呈现的索引页面上,则将看到AuthLayoutDashboardLayout也是如此。哪种有点有意义,因为它们没有包装在Route中。

有人建议获取所有布局的内容,并将其作为同级添加到当前路径中。但这对我来说是一团糟。我确实希望将所有布局保留在单独的文件中,并且仅将屏幕作为子项传递给它们。

任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:1)

这是潜在布局结构的粗略草稿:

<Header>
  <Router>
    <Router path={['/index', '/about']} component={HeaderComponent} />
    <Router path={['/sign-in', '/sign-up']} component={AuthHeaderComponent} />
  </Router>
</Header>
<Screens>
  <Router>
    <Route path="/index" component={BaseLayout(Index)} />
    <Route path="/about" component={BaseLayout(About)} />
    <Route path="/sign-in" component={AuthLayout(SignIn)} />
    <Route path="/sign-up" component={AuthLayout(SignUp)} />
    <Route path="/stats" component={DashboardLayout(Stats)} />
  </Router>
</Screens>
<Footer>
  <FooterComponent />
</Footer>

在此示例中,包装器是HOC,因此它们可以处理将所有道具从路线向下传递到页面组件的操作,但是,如果您只是想进行内联包装器,则可以使用render函数:

<Route
  path="/index"
  render={routeProps => {
    return (
      <BaseLayout>
        <Index {...routeProps}/>
      </BaseLayout>
    );
  }}
/>

[edit]一个示例版式HOC(docs

const withBaseLayout = WrappedComponent => {
  // any business logic required for the layout
  // layoutProps, style, etc...
  return (
    <BaseLayout {...layoutProps}>
      <WrappedComponent {...this.props} /> // these are all the passed in props
      // you can inject more props into Wrapped component as well
      // i.e. redux's connect or react-router-dom's withRouter HOCs
    </BaseLayout>
  );
}

// in index.js
export default withBaseLayout(Index);

// in route
<Route path="/index" component={Index} /> // already wrapped

或直接作为组件

const BaseLayoutHOC = WrappedComponent => {
  // any business logic required for the layout
  // layoutProps, style, etc...
  return (
    <BaseLayout {...layoutProps}>
      <WrappedComponent {...this.props} />
    </BaseLayout>
  );
}

// in route
<Route path="/index" component={BaseLayoutHOC(Index)} />

答案 1 :(得分:-1)

尝试在每条路线中添加精确值,然后将组件传递到内部

索引} />

import  { Switch , Route  } from 'react-router-dom';

<BrowserRouter>
 
    <Route path="/index" exact component={<BaseLayout>Index </BaseLayout>} />
    <Route path="/about" exact component={<BaseLayout>About</BaseLayout>} />  
    <Route path="/sign-in" exactcomponent={ <AuthLayout>SignIn </AuthLayout>} />
    <Route path="/sign-up" exact component={ <AuthLayout>SignUp </AuthLayout>} />
    <Route path="/stats" exact component={            <DashboardLayout>Stats</DashboardLayout>} />

</BrowserRouter>

希望这对您有帮助