2017-02-15 113 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> 
);