2015-08-20 13 views
48

Beachten Sie Folgendes:React-Router: Keine nicht gefundene Route?

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

Ich habe eine App-Vorlage, eine Header und Parameterized Satz von Routen mit demselben Handler (in App-Vorlage). Ich möchte 404 Routen bedienen können, wenn etwas nicht gefunden wird. Zum Beispiel sollte/CA/SanFrancisco von Area gefunden und bearbeitet werden, während/SanFranciscoz sollte 404.

So kann ich die Routen schnell testen.

['', '/', '/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'); 
    }); 
}); 

Das Problem wird/SanFranciscoz wird immer durch die Gegend Seite umgegangen wird, aber ich möchte es 404. Auch wenn ich eine NotFoundRoute auf der ersten Route Konfiguration hinzufügen, werden alle Bereichsseiten 404.

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

Was mache ich falsch?

Hier ist ein Kern, der heruntergeladen und experimentiert werden kann.

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

Antwort

92

Dejakob Antwort richtig ist, und default NotFoundRoute wurden entfernt in reagieren-Router 1.0.0. Ich möchte betonen, dass die Standardroute mit dem Stern letzte in der aktuellen Hierarchieebene sein muss, um zu arbeiten. Andernfalls werden alle Routen, die danach im Baum angezeigt werden, zugeordnet.

Für reagieren-Router 1, 2 und 3

Wenn Sie eine 404 und angezeigt werden soll halten den Pfad (gleiche Funktionalität wie NotFoundRoute)

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

Wenn Sie anzeigen möchten, a 404 Seite aber ändern Sie die URL (gleiche Funktionalität wie DefaultRoute)

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

Beispiel mit mehreren Ebenen:

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

Für reagieren-Router 4

den Pfad Halten

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

Umleiten zu einem anderen Weg (Veränderung url)

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

wenn du eine Redux-App hast, wie machst du: ' 'in dieser Syntax:' const routes = { Komponente: Main, childRoutes: [ {path: '/', Komponente: Home}, ], indexRoute: { Komponente: Main, }, }; ' – tatsu

+0

wenn Sie Requisiten setzen für die 404-Compontent verwenden diese wollen Code: '} />' –

1

Ich hatte nur einen kurzen Blick auf Ihrem Beispiel, aber wenn ich es richtig verstanden Sie versuchen, 404 Routen zu dynamischen Segmente hinzuzufügen. Ich hatte das gleiche Problem vor ein paar Tagen, gefunden #458 und #1103 und endete mit einer Hand gemacht Prüfung innerhalb der Render-Funktion nach oben:

if (!place) return <NotFound />; 

Hoffnung, das hilft!

+0

dank @jorn, ich glaube, du hast Recht, dies scheint adressierbar nur von der Komponentenebene – 4m1r

2

Nach der documentation wurde die Route "wurde" gefunden, obwohl die Ressource nicht war.

Hinweis: Dies soll nicht verwendet werden, wenn eine Ressource nicht gefunden wird. Es besteht ein Unterschied zwischen dem Router, der keinen übereinstimmenden Pfad findet und einer gültigen URL, die dazu führt, dass eine Ressource nicht gefunden wird. Die URL-Kurse/123 ist eine gültige URL und führt zu einer angepassten Route, daher wurde sie "gefunden", was das Routing betrifft. Wenn wir dann einige Daten abrufen und feststellen, dass der Kurs 123 nicht existiert, wollen wir nicht zu einer neuen Route übergehen. Genau wie auf dem Server, gehen Sie weiter und liefern die URL, aber rendern unterschiedliche Benutzeroberfläche (und verwenden Sie einen anderen Statuscode). Sie sollten niemals versuchen, auf eine NotFoundRoute umzusteigen.

Also, man konnte immer eine Zeile in den Router.run() vor React.render() hinzufügen zu überprüfen, ob die Ressource gültig ist. Übergeben Sie einfach eine Requisite an die Komponente oder überschreiben Sie die Handler Komponente mit einer benutzerdefinierten Komponente, um die NotFound-Ansicht anzuzeigen.

+0

dank @brad, sind Sie richtig, Sie haben dies mit der Komponente zu handhaben und/oder überschreiben Sie den Handler vor router.run – 4m1r

+3

NotFound wurde veraltet https://github.com/reactjs/react-router/releases/tag/v1.0.0, jetzt verwenden Sie ' oder '' als die letzte Unterroute, die ich finde, glaube ich, – ptim

11

Mit der neuen Version von React Router (die jetzt 2.0.1 verwendet) können Sie einen Stern als Pfad verwenden, um alle anderen Pfade zu routen.

So würde es so aussehen:

<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 neueren Versionen von react-Router möchten Sie wrap the routes in a Switch, die nur die erste übereinstimmende Komponente rendert. Andernfalls würden Sie mehrere Komponenten gerendert sehen.

Zum Beispiel:

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

Sie müssen nicht 'path =" * "' auf der NotFound Route. Das Weglassen von "Pfad" bewirkt, dass die Route immer übereinstimmt. – chipit24

Verwandte Themen