web-dev-qa-db-fra.com

Comment imbriquer des routes dans React Router v4?

Existe-t-il un moyen d'imbriquer des routes dans React Router v4?

Cela marche:

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

Cela ne veut pas:

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

Composante Clients:

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;
`
17
Raphael Rafatpanah

Meilleur modèle que j'ai trouvé jusqu'à présent. 

// 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>

Je peux simplement garder cette imbrication dans un composant et tout fonctionne bien, y compris hmr (si vous utilisez webpack, n'oubliez pas de définir output.publicPath sur "/")

// 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>
29
CESCO

J'ai adapté cela à partir de la documentation, semble fonctionner jusqu'à présent. Manque probablement quelque chose d’évident, et oui ce n’est pas la manière de v4 mais nous avons besoin de toutes les routes définies au même endroit.

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>
7
soundyogi

Votre composant AppBar est chargé de rendre les clients. Pour que les clients soient appelés, vous devez rendre les enfants de AppBar. Tout ce qui est directement imbriqué dans AppBar est un enfant de AppBar. 

import React from 'react';

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

export default AppBar

Veuillez noter que seul AppBar sera rendu lorsque vous visiterez "/". AppBar et les clients seront rendus lors de votre visite à "/ clients".

1
ExperimentsWithCode

Si quelqu'un veut avoir des routes imbriquées sans saisir le préfixe de la route wrapper, j'ai créé quelque chose comme ceci dans TSX:

Importations:

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';

Interfaces:

interface INestedRoutes {
    nested?: string;
}

interface INestedRoute extends RouteProps, INestedRoutes {}

Enveloppeurs NestedRoute et 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} />;
};

Et itinéraires avec wrapper:

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>
);
1
Marcin Sadowski

Pour les routes imbriquées, il existe un moyen très simple que j’utilise. 

Exemple routeur principal est être comme ça 

<Router history={history}>
  <Switch >
    <Route path="/" component={Home}></Route>
  </Switch>
</Router>

Le composant Inside Home utilisant le routage imbriqué soit comme: 

<div className="App">
  <Navbar title="Home" links = { NavbarLinks }/>
  {this.renderContentPage()}
</div>

renderContentPage va vérifier l'URL et rendre la route imbriquée.

<Route exact path="/" component={Page1}></Route>
<Route exact path="/page1" component={Page1}></Route>
<Route exact path='/page2' component={Page2} />

Donc, à l'intérieur des composants Accueil page1 et page2 composants rendus. 

0
Hadnazzar