2015-10-11 23 views
46

Aggiungo router di risposta a un progetto esistente.Utilizzo di React-Router con una pagina di layout o più componenti per pagina

Attualmente un modello viene passato a un componente radice che contiene un componente di navigazione per la navigazione secondaria e un componente principale.

Gli esempi di router di risposta che ho trovato hanno solo un componente figlio, qual è il modo migliore per cambiare più componenti figlio senza ripetere il codice di layout in entrambi?

+0

Ciao Tom, volevo solo sapere se hai trovato un modo per aggirare questo? Ho cercato e cercato per due giorni di importare direttamente un componente ma non funziona. – hudsond7

risposta

91

Se ho capito bene, per ottenere ciò si definiscono più componenti nel proprio Route. Si può usare come:

// think of it outside the context of the router, if you had pluggable 
// portions of your `render`, you might do it like this 
<App children={{main: <Users/>, sidebar: <UsersSidebar/>}}/> 

// So with the router it looks like this: 
const routes = (
    <Route component={App}> 
    <Route path="groups" components={{main: Groups, sidebar: GroupsSidebar}}/> 
    <Route path="users" components={{main: Users, sidebar: UsersSidebar}}> 
     <Route path="users/:userId" component={Profile}/> 
    </Route> 
    </Route> 
) 

class App extends React.Component { 
    render() { 
    const { main, sidebar } = this.props; 
    return (
     <div> 
     <div className="Main"> 
      {main} 
     </div> 
     <div className="Sidebar"> 
      {sidebar} 
     </div> 
     </div> 
    ) 
    } 
} 

class Users extends React.Component { 
    render() { 
    return (
     <div> 
     {/* if at "https://stackoverflow.com/users/123" `children` will be <Profile> */} 
     {/* UsersSidebar will also get <Profile> as this.props.children, 
      so its a little weird, but you can decide which one wants 
      to continue with the nesting */} 
     {this.props.children} 
     </div> 
    ) 
    } 
} 

controllare anche le sidebar example app, dovrebbe aiutare di più.

Edit: Secondo il commento di @ Luiz:

Nella versione più recente del router (v3) i componenti sono nella radice dei puntelli oggetto

Quindi:

const { main, sidebar } = this.props.children; 

diventa:

const { main, sidebar } = this.props; 

EDIT: Nel reagire-router v4 questo può essere realizzato come (come per l'esempio fornito nel new docs):

import React from 'react' 
import { 
    BrowserRouter as Router, 
    Route, 
    Link 
} from 'react-router-dom' 

// Each logical "route" has two components, one for 
// the sidebar and one for the main area. We want to 
// render both of them in different places when the 
// path matches the current URL. 
const routes = [ 
    { path: '/', 
    exact: true, 
    sidebar:() => <div>home!</div>, 
    main:() => <h2>Home</h2> 
    }, 
    { path: '/bubblegum', 
    sidebar:() => <div>bubblegum!</div>, 
    main:() => <h2>Bubblegum</h2> 
    }, 
    { path: '/shoelaces', 
    sidebar:() => <div>shoelaces!</div>, 
    main:() => <h2>Shoelaces</h2> 
    } 
] 

const SidebarExample =() => (
    <Router> 
    <div style={{ display: 'flex' }}> 
     <div style={{ 
     padding: '10px', 
     width: '40%', 
     background: '#f0f0f0' 
     }}> 
     <ul style={{ listStyleType: 'none', padding: 0 }}> 
      <li><Link to="/">Home</Link></li> 
      <li><Link to="/bubblegum">Bubblegum</Link></li> 
      <li><Link to="/shoelaces">Shoelaces</Link></li> 
     </ul> 

     {routes.map((route, index) => (
      // You can render a <Route> in as many places 
      // as you want in your app. It will render along 
      // with any other <Route>s that also match the URL. 
      // So, a sidebar or breadcrumbs or anything else 
      // that requires you to render multiple things 
      // in multiple places at the same URL is nothing 
      // more than multiple <Route>s. 
      <Route 
      key={index} 
      path={route.path} 
      exact={route.exact} 
      component={route.sidebar} 
      /> 
     ))} 
     </div> 

     <div style={{ flex: 1, padding: '10px' }}> 
     {routes.map((route, index) => (
      // Render more <Route>s with the same paths as 
      // above, but different components this time. 
      <Route 
      key={index} 
      path={route.path} 
      exact={route.exact} 
      component={route.main} 
      /> 
     ))} 
     </div> 
    </div> 
    </Router> 
) 

export default SidebarExample 

Assicurati di controllare il nuovo React Router v4 docs qui: https://reacttraining.com/react-router/

+2

Nella versione più recente del router i componenti si trovano nella radice dell'oggetto oggetti di scena. –

+0

Copia/Incolla? Molto bene. Downvote – Green

+0

Come si ottengono parametri di percorso dinamici al componente, seguendo l'esempio v4? Questo non è delineato nei documenti. – Faust

7

Il componente può essere una funzione che restituisce JSX.

<Route> 
    <Route path="/" component={App}> 
     <IndexRoute component={Home} /> 
     <Route path="Invite" component={()=>(<div><Home/><Invite/></div>)} /> 
    </Route> 
    </Route> 
Problemi correlati