Percorsi nidificati con il router di reazione v4 / v5


262

Attualmente sto lottando con i percorsi di nidificazione utilizzando il router di reazione v4.

L'esempio più vicino è stata la configurazione del percorso nella documentazione di React-Router v4 .

Voglio dividere la mia app in 2 parti diverse.

Un frontend e un'area di amministrazione.

Stavo pensando a qualcosa del genere:

<Match pattern="/" component={Frontpage}>
  <Match pattern="/home" component={HomePage} />
  <Match pattern="/about" component={AboutPage} />
</Match>
<Match pattern="/admin" component={Backend}>
  <Match pattern="/home" component={Dashboard} />
  <Match pattern="/users" component={UserPage} />
</Match>
<Miss component={NotFoundPage} />

Il frontend ha un layout e uno stile diversi rispetto all'area di amministrazione. Quindi, in prima pagina, il percorso verso casa, circa e quindi si dovrebbero essere i percorsi secondari.

/ home dovrebbe essere renderizzato nel componente Frontpage e / admin / home dovrebbe essere reso nel componente Backend.

Ho provato alcune varianti ma ho sempre finito per non colpire / home o / admin / home.

Modifica - 19.04.2017

Poiché questo post ha molte visualizzazioni in questo momento, l'ho aggiornato con la soluzione finale. Spero che aiuti qualcuno.

Modifica - 08.05.2017

Rimosse vecchie soluzioni

Soluzione finale:

Questa è l'ultima soluzione che sto usando in questo momento. Questo esempio ha anche un componente di errore globale come una pagina 404 tradizionale.

import React, { Component } from 'react';
import { Switch, Route, Redirect, Link } from 'react-router-dom';

const Home = () => <div><h1>Home</h1></div>;
const User = () => <div><h1>User</h1></div>;
const Error = () => <div><h1>Error</h1></div>

const Frontend = props => {
  console.log('Frontend');
  return (
    <div>
      <h2>Frontend</h2>
      <p><Link to="/">Root</Link></p>
      <p><Link to="/user">User</Link></p>
      <p><Link to="/admin">Backend</Link></p>
      <p><Link to="/the-route-is-swiggity-swoute">Swiggity swooty</Link></p>
      <Switch>
        <Route exact path='/' component={Home}/>
        <Route path='/user' component={User}/>
        <Redirect to={{
          state: { error: true }
        }} />
      </Switch>
      <footer>Bottom</footer>
    </div>
  );
}

const Backend = props => {
  console.log('Backend');
  return (
    <div>
      <h2>Backend</h2>
      <p><Link to="/admin">Root</Link></p>
      <p><Link to="/admin/user">User</Link></p>
      <p><Link to="/">Frontend</Link></p>
      <p><Link to="/admin/the-route-is-swiggity-swoute">Swiggity swooty</Link></p>
      <Switch>
        <Route exact path='/admin' component={Home}/>
        <Route path='/admin/user' component={User}/>
        <Redirect to={{
          state: { error: true }
        }} />
      </Switch>
      <footer>Bottom</footer>
    </div>
  );
}

class GlobalErrorSwitch extends Component {
  previousLocation = this.props.location

  componentWillUpdate(nextProps) {
    const { location } = this.props;

    if (nextProps.history.action !== 'POP'
      && (!location.state || !location.state.error)) {
        this.previousLocation = this.props.location
    };
  }

  render() {
    const { location } = this.props;
    const isError = !!(
      location.state &&
      location.state.error &&
      this.previousLocation !== location // not initial render
    )

    return (
      <div>
        {          
          isError
          ? <Route component={Error} />
          : <Switch location={isError ? this.previousLocation : location}>
              <Route path="/admin" component={Backend} />
              <Route path="/" component={Frontend} />
            </Switch>}
      </div>
    )
  }
}

class App extends Component {
  render() {
    return <Route component={GlobalErrorSwitch} />
  }
}

export default App;

1
Grazie per aver aggiornato la tua domanda con la risposta finale! solo un suggerimento: forse potresti mantenere solo il 4 ° e il primo elenco, poiché gli altri stanno usando versioni obsolete dell'API e stanno distraendo dalla risposta
Giuliano Vilela,

lol, non ho idea di che formato sia questa data: 08.05.2017 Ti suggerisco di usare il formato ISO8601 universale per le date se non vuoi confondere le persone. sono 08 il mese o il giorno? ISO8601 = year.month.day hour.minute.second (progressivamente più granulare)
wesm

Bella soluzione finale aggiornata, ma penso che non sia necessaria la previousLocationlogica.
tudorpavel,

qual è la motivazione per riscrivere completamente il router di reazione. È meglio che sia una buona ragione
Oliver Watkins,

È l'approccio dichiarativo. Quindi puoi impostare i tuoi percorsi come utilizzeresti i componenti di reazione.
datoml

Risposte:


318

In reagire-router-v4 non si annida <Routes />. Invece, li metti dentro un altro <Component />.


Per esempio

<Route path='/topics' component={Topics}>
  <Route path='/topics/:topicId' component={Topic} />
</Route>

dovrebbe diventare

<Route path='/topics' component={Topics} />

con

const Topics = ({ match }) => (
  <div>
    <h2>Topics</h2>
    <Link to={`${match.url}/exampleTopicId`}>
      Example topic
    </Link>
    <Route path={`${match.path}/:topicId`} component={Topic}/>
  </div>
) 

Ecco un esempio di base direttamente dalla documentazione di reagente-router .


sono in grado di implementare dal tuo link nell'esempio di base, tuttavia quando scrivo l'URL manualmente non funziona sul mio server localhost. ma lo fa sul tuo esempio. D'altra parte, HashRouter funziona correttamente quando scrivo l'URL manualmente con #. Hai idea del perché sul mio server localhost BrowserRouter non funziona quando scrivo l'URL manualmente?
himawan_r,

8
puoi trasformare il componente Argomenti in una classe? e da dove viene il parametro 'match'? nel render ()?
user1076813

21
Sembra ridicolo non è possibile solo to="exampleTopicId"con l' ${match.url}essere implicito.
greenimpala,

8
Puoi avere percorsi nidificati per i documenti reattraining.com/react-router/web/example/route-config . Ciò consentirebbe una configurazione centralizzata del percorso come da argomento nei documenti. Pensa quanto sarebbe folle gestire un progetto più ampio se non disponibile.
JustDave,

5
Questi non sono percorsi nidificati, è un routing a un livello che utilizza ancora la proprietà render di una route che accetta un componente funzionale come input, guarda più attentamente, non c'è nidificazione nel senso di reagire al router <4. RouteWithSubRoutes è una -livello elenco di rotte che utilizzano la corrispondenza dei modelli.
Lyubomir,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.