React-Router: ¿No se encontró ninguna ruta?

Resuelto 4m1r asked hace 9 años • 11 respuestas

Considera lo siguiente:

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

Tengo una plantilla de aplicación, una plantilla de encabezado y un conjunto de rutas parametrizadas con el mismo controlador (dentro de la plantilla de la aplicación). Quiero poder atender rutas 404 cuando no se encuentra algo. Por ejemplo, /CA/SanFrancisco debe ser encontrado y manejado por Área, mientras que /SanFranciscoz debe ser 404.

Así es como pruebo rápidamente las rutas.

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

El problema es que /SanFranciscoz siempre está siendo manejado por la página Área, pero quiero que sea 404. Además, si agrego NotFoundRoute a la primera configuración de ruta, todas las páginas Área 404.

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

¿Qué estoy haciendo mal?

Aquí hay una esencia que se puede descargar y experimentar.

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

4m1r avatar Aug 21 '15 04:08 4m1r
Aceptado

DefaultRoute y NotFoundRoute se eliminaron en reaccionar-router 1.0.0.

Me gustaría enfatizar que la ruta predeterminada con el asterisco debe ser la última en el nivel de jerarquía actual para funcionar. De lo contrario, anulará todas las demás rutas que aparecen después en el árbol porque es la primera y coincide con todas las rutas.

Para los enrutadores de reacción 1, 2 y 3

Si desea mostrar un 404 y conservar la ruta (misma funcionalidad que NotFoundRoute)

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

Si desea mostrar una página 404 pero cambiar la URL (misma funcionalidad que DefaultRoute)

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

Ejemplo con múltiples niveles:

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

Para los enrutadores de reacción 4 y 5

mantener el camino

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

Redirigir a otra ruta (cambiar URL)

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

¡El orden importa!

Janne Annala avatar May 27 '2016 19:05 Janne Annala

En las versiones más nuevas de reaccionar-router, desea envolver las rutas en un Switch que solo representa el primer componente coincidente. De lo contrario, verás varios componentes renderizados.

Por ejemplo:

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 component={NotFound}/>
    </Switch>
  </Router>
);

ReactDOM.render(
  <Root/>,
  document.getElementById('root')
);
metakermit avatar Apr 07 '2017 18:04 metakermit

Con la nueva versión de React Router (que ahora usa 2.0.1), puede usar un asterisco como ruta para enrutar todas las "otras rutas".

Entonces quedaría así:

<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>
dejakob avatar Apr 20 '2016 08:04 dejakob

Esta respuesta es para reaccionar-enrutador-4. Puede envolver todas las rutas en el bloque Switch, que funciona igual que la expresión switch-case y representa el componente con la primera ruta coincidente. p.ej)

<Switch>
      <Route path="/" component={home}/>
      <Route path="/home" component={home}/>
      <Route component={GenericNotFound}/> {/* The Default not found component */}
</Switch>

Cuándo usarexact

Sin exacto:

<Route path='/home'
       component = {Home} />

{/* This will also work for cases like https://<domain>/home/anyvalue. */}

Con exacto:

<Route exact path='/home'
       component = {Home} />

{/* 
     This will NOT work for cases like https://<domain>/home/anyvalue. 
     Only for https://<url>/home and https://<domain>/home/
*/}

Ahora, si acepta parámetros de enrutamiento y resulta incorrecto, puede manejarlo en el propio componente de destino. p.ej)

<Route exact path='/user/:email'
       render = { (props) => <ProfilePage {...props} user={this.state.user} />} />

Ahora en ProfilePage.js

if(this.props.match.params.email != desiredValue)
{
   <Redirect to="/notFound" component = {GenericNotFound}/>
   //Or you can show some other component here itself.
}

Para obtener más detalles, puede consultar este código:

aplicación.js

Página de perfil.js

Pransh Tiwari avatar Jun 22 '2018 12:06 Pransh Tiwari