2015-08-20 17 views
48

Si consideri il seguente:React-Router: No Route non trovata?

var AppRoutes = [ 
    <Route handler={App} someProp="defaultProp"> 
     <Route path="/" handler={Page} /> 
    </Route>, 

    <Route handler={App} someProp="defaultProp"> 
     <Route path="/" handler={Header} > 
      <Route path="/withheader" handler={Page} /> 
     </Route> 
    </Route>, 

    <Route handler={App} someProp="defaultProp"> 
     <Route path=":area" handler={Area} /> 
     <Route path=":area/:city" handler={Area} /> 
     <Route path=":area/:city/:locale" handler={Area} /> 
     <Route path=":area/:city/:locale/:type" handler={Area} /> 
    </Route> 
]; 

Ho un modello di App, un HeaderTemplate, e insieme con parametri di percorsi con lo stesso gestore (nel modello di applicazione). Voglio essere in grado di servire 404 percorsi quando qualcosa non viene trovato. Ad esempio,/CA/SanFrancisco dovrebbe essere trovato e gestito da Area, mentre/SanFranciscoz dovrebbe 404.

Ecco come posso testare rapidamente i percorsi.

['', '/', '/withheader', '/SanFranciscoz', '/ca', '/CA', '/CA/SanFrancisco', '/CA/SanFrancisco/LowerHaight', '/CA/SanFrancisco/LowerHaight/condo'].forEach(function(path){ 
    Router.run(AppRoutes, path, function(Handler, state){ 
     var output = React.renderToString(<Handler/>); 
     console.log(output, '\n'); 
    }); 
}); 

Il problema è/SanFranciscoz è sempre gestita dalla pagina di area, ma voglio che 404. Inoltre, se posso aggiungere un NotFoundRoute alla prima configurazione percorso, tutte le pagine Area 404.

<Route handler={App} someProp="defaultProp"> 
    <Route path="/" handler={Page} /> 
    <NotFoundRoute handler={NotFound} /> 
</Route>, 

Cosa sto sbagliando?

Ecco un elenco che può essere scaricato e sperimentato.

https://gist.github.com/adjavaherian/aa48e78279acddc25315

risposta

92

di Dejakob è corretta, defaultroute e NotFoundRoute sono stati rimossi nel reagire-router 1.0.0. Vorrei sottolineare che il percorso predefinito con l'asterisco deve essere lo scorso al livello di gerarchia attuale per funzionare. Altrimenti corrisponderà a tutti i percorsi che verranno visualizzati dopo di esso nell'albero.

Per reagire-router 1, 2 e 3

Se si desidera visualizzare un 404 e mantenere il percorso (Stesso funzionalità NotFoundRoute)

<Route path='*' exact={true} component={My404Component} /> 

Se si desidera visualizzare una pagina 404 ma modificare l'url (stessa funzionalità di DefaultRoute)

<Route path='/404' component={My404Component} /> 
<Redirect from='*' to='/404' /> 

Esempio con più livelli:

<Route path='/' component={Layout} /> 
    <IndexRoute component={MyComponent} /> 
    <Route path='/users' component={MyComponent}> 
     <Route path='user/:id' component={MyComponent} /> 
     <Route path='*' component={UsersNotFound} /> 
    </Route> 
    <Route path='/settings' component={MyComponent} /> 
    <Route path='*' exact={true} component={GenericNotFound} /> 
</Route> 

Per reagire-router 4

Mantenere il percorso

<Switch> 
    <Route exact path="/" component={MyComponent} /> 
    <Route component={GenericNotFound} /> 
</Switch> 

Redirect ad un altro percorso (cambio url)

<Switch> 
    <Route path="/users" component={MyComponent} /> 
    <Redirect to="/404" /> 
</Switch> 
+0

se hai un'app di redux come fai: ' 'in questa sintassi:' const routes = { component: Main, childRoutes: [ {path: '/', componente: Home}, ], indexRoute: { componenti: Principale, }, }; ' – tatsu

+0

se si desidera impostare puntelli per il 404-Compontent utilizzare questo codice: '} />' –

1

Ho appena avuto una rapida occhiata al tuo esempio, ma se ho capito nel modo giusto si sta cercando di aggiungere 404 percorsi ai segmenti dinamici. Ho avuto lo stesso problema un paio di giorni fa, ho trovato #458 e #1103 e finito con un assegno intestato a mano all'interno della funzione di rendering:

if (!place) return <NotFound />; 

speranza che aiuta!

+0

grazie @jorn, penso che tu abbia ragione, questo sembra indirizzabili solo dal livello di componente – 4m1r

2

In base allo documentation, il percorso "è stato trovato", anche se la risorsa non lo era.

Nota: Questo non è destinato ad essere utilizzato per quando non si trova una risorsa. Esiste una differenza tra il router che non trova un percorso corrispondente e un URL valido che determina il mancato rilevamento di una risorsa. I corsi/123 url è un url valido e si traduce in un percorso corrispondente, pertanto è stato "trovato" per quanto riguarda il routing. Quindi, se recuperiamo alcuni dati e scopriamo che il corso 123 non esiste, non vogliamo passare a una nuova rotta. Proprio come sul server, vai avanti e servi l'url ma rendi diversa interfaccia utente (e usa un codice di stato diverso). Non dovresti mai provare a passare a NotFoundRoute.

Quindi, si può sempre aggiungere una riga nella prima Router.run()React.render() per verificare se la risorsa è valida. Basta passare un puntello al componente o ignorare il componente Handler con uno personalizzato per visualizzare la vista NotFound.

+0

grazie @brad, hai ragione, è necessario gestire questo con il componente o ignorare il gestore prima di router.run – 4m1r

+3

NotFound è stato deprecato https://github.com/reactjs/react-router/releases/tag/v1.0.0, ora utilizzare '' o '' come ultima rotta secondaria da abbinare, credo che – ptim

11

Con la nuova versione di React Router (utilizzando 2.0.1 ora), è possibile utilizzare un asterisco come percorso per il routing di tutti gli "altri percorsi".

Quindi sarebbe simile a questa: risposta

<Route route="/" component={App}> 
    <Route path=":area" component={Area}> 
     <Route path=":city" component={City} /> 
     <Route path=":more-stuff" component={MoreStuff} />  
    </Route> 
    <Route path="*" component={NotFoundRoute} /> 
</Route> 
11

In più recente versioni di react-router che si desidera wrap the routes in a Switch che esegue solo il rendering del primo componente corrispondente. Altrimenti vedresti più componenti renderizzati.

Ad esempio:

import React from 'react'; 
import ReactDOM from 'react-dom'; 
import { 
    BrowserRouter as Router, 
    Route, 
    browserHistory, 
    Switch 
} from 'react-router-dom'; 

import App from './app/App'; 
import Welcome from './app/Welcome'; 
import NotFound from './app/NotFound'; 

const Root =() => (
    <Router history={browserHistory}> 
    <Switch> 
     <Route exact path="/" component={App}/> 
     <Route path="/welcome" component={Welcome}/> 
     <Route path="*" component={NotFound}/> 
    </Switch> 
    </Router> 
); 

ReactDOM.render(
    <Root/>, 
    document.getElementById('root') 
); 
+3

Non è necessario includere 'path =" * "' sul Percorso NotFound. Omettendo 'path' farà sempre coincidere il percorso. – chipit24