2017-02-15 85 views
12

有没有在React Router v4中嵌套路由的方法?如何在React Router v4中嵌套路由?

这工作:

<Router basename='/app'> 
    <main> 
     <Route path='/' component={AppBar} /> 
     <Route path='/customers' component={Customers} /> 
    </main> 
    </Router> 

这不:

<Router basename='/app'> 
    <Route path='/' component={AppBar}> 
     <Route path='/customers' component={Customers} /> 
    </Route> 
    </Router> 

客户组件:

import React, { Component, PropTypes } from 'react' 
import styled from 'styled-components' 

export default class Customers extends Component { 
    render() { 
    return (
     <Container> 
     <h1>Customers</h1> 
     </Container> 
    ) 
    } 
} 

const Container = styled.section` 
    height: 100%; 
    padding: 15px; 
    overflow: auto; 
` 
+0

@ExperimentsWithCode,我主要是想看看是否有避免需要包装的方式(即'

')因为''只能有一个孩子。 –

+0

你是否得到一个错误,因为我做你的'不',它工作正常。 – ExperimentsWithCode

+0

在第二个示例中,“Customers”组件不呈现。 –

回答

24

迄今为止发现的最佳模式。

// main app 
<div> 
    // not setting a path prop, makes this always render 
    <Route component={AppShell}/> 
    <Switch> 
     <Route exact path="/" component={Login}/> 
     <Route path="/dashboard" component={AsyncDashboard(userAgent)}/> 
     <Route component={NoMatch}/> 
    </Switch> 
</div> 

我可以只保留一个组成部分嵌套了这一点,一切工作不错,包括HMR(如果使用的WebPack,不要忘记设置output.publicPath"/"

// dashboard component 
<div> 
    // the same way as before, not setting a path prop 
    // makes it render on every /dashboard/** request 
    <Route component={DashboardTAB}/> 
    <Switch> 
     // longer path (with same root) than others first 
     <Route path="/dashboard/graphs/longerpath" component={GraphForm}/> 
     <Route path="/dashboard/graphs" component={Graphs}/> 
     <Route path="/dashboard/workers" component={List}/> 
     <Route path="/dashboard/insert" component={InsertComponent}/> 
    </Switch> 
</div> 
+0

我这样做,但有一个父母的布局,这是正确运行,没有错误,但只显示(在组件中)的第一条路线,当我点击一个链接时没有页面更改,即时使用webpack太,并把output.publicPath正如你所说..任何想法另一个问题? thx – pirs

+0

完美无瑕,我刚开始使用最短路径的第一条路线,以便将最短路径作为唯一可用路径。 – pirs

+0

不设置路径prop解决了我遇到的问题。谢谢! – NaN

1

你AppBar组件负责渲染客户。对于要调用的客户,您必须呈现AppBar的子项。直接嵌套在AppBar下的任何东西都是AppBar的子元素。

import React from 'react'; 

const AppBar = ({ children }) => (
    <div> 
    <header> 
     <h1> stuff </h1> 
    </header> 
    {children} 
    </div> 
); 

export default AppBar 

请注意,只有AppBar会在您访问“/”时呈现。 AppBar和客户将在您访问“/ customers”时进行呈现。

+0

即使呈现''的'{children} ',嵌套在React Router v4中时''组件不会呈现。 –

+0

,你在URL“/ customers”? – ExperimentsWithCode

+0

是的。 '/应用程序/客户'。当没有嵌套时,''组件在该URL处呈现。 –

5

我适应这个从文档,似乎到目前为止工作。可能缺少一些明显的东西,是的,它不是v4的方式,但我们需要在一个地方定义的所有路线。

function RouteNest(props){ return (
    <Route exact={props.exact} path={props.path} render={ p => <props.component {...p} children={props.children}/> } /> 
)} 

export const MainRoutes = props => 

<div className='content layout'> 

    <Route exact path="/" component={Landing}/> 
    <Route path={'/contact'} component={Contact}/> 

    <RouteNest path={'/thing'} component={CompoWithSub}> 
    <RouteNest path={'/thing/suba'} component={SubComponentA}/> 
    <RouteNest path={'/thing/subb'} component={SubComponentB}/> 
    </RouteNest> 


</div> 

export const CompoWithSub = props => <div>{props.children)</div> 
+0

这是正确的答案 – evanjmg

1

如果有人想嵌套的路线,而无需输入我已经创建了这样的事情在TSX包装路线的前缀:

进口:

import * as React from 'react'; 
import { Route, RouteComponentProps, RouteProps, Switch } from 'react-router-dom'; 
import Index from 'views/index'; 
import Login from 'views/login'; 
import NoMatch from 'views/no-match'; 

接口:

interface INestedRoutes { 
    nested?: string; 
} 

interface INestedRoute extends RouteProps, INestedRoutes {} 

NestedRoute和NestedRoutes包装:

class NestedRoutes extends React.Component<INestedRoutes> { 
    public render() { 
     const childrenWithProps = React.Children.map(this.props.children, (child) => { 
      return React.cloneElement(
       child as React.ReactElement<any>, { nested: this.props.nested }, 
      ); 
     }) 
     return childrenWithProps; 
    } 
} 


const NestedRoute: React.SFC<INestedRoute> = (props: INestedRoute) => { 
    return <Route path={`${props.nested}${props.path}`} component={props.component} />; 
}; 

和路线与包装:

const MultiLanguage: React.SFC<RouteComponentProps<any>> = (props: RouteComponentProps<any>) => { 
    return (
     <NestedRoutes nested={props.match.path} > 
      <NestedRoute path="/test" component={Login} /> 
      <NestedRoute path="/no-match" component={NoMatch} /> 
     </NestedRoutes> 
    ); 
}; 


export default (
    <Switch> 
     <Route path="/:language" component={MultiLanguage}/> 
     <Route exact={true} path="/" component={Index} /> 
     <Route path="/login" component={Login} /> 
     <Route component={NoMatch} /> 
    </Switch> 
);