[英]How do I nest routes with React router
我有多个布局,应该包括不同的屏幕。 每个布局都有自己的 header、页脚和其他类似页面应该共享的内容。 这是我想出的代码:
<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
内呈现的索引页面上,您也会看到来自AuthLayout
和DashboardLayout
的元素。 这有点道理,因为它们没有被包裹在Route
中。
有人建议抓取所有布局的内容并将它们作为兄弟姐妹添加到当前路由中。 然而,这对我来说是一团糟。 我确实想将所有布局保存在单独的文件中,并且只将屏幕作为子项传递给它们。
这是潜在布局结构的粗略草图:
<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,因此它们可以处理将所有道具从路由向下传递到页面组件,但如果您只想做一个内联包装器,您可以使用渲染function:
<Route
path="/index"
render={routeProps => {
return (
<BaseLayout>
<Index {...routeProps}/>
</BaseLayout>
);
}}
/>
[编辑] 一个示例布局 HOC(文档)
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)} />
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.