React-Router: Нет Не Найден Маршрут?

рассмотрим следующее:

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

У меня есть шаблон приложения, HeaderTemplate и параметризованный набор маршрутов с тем же обработчиком (в шаблоне приложения). Я хочу иметь возможность обслуживать 404 маршрута, когда что-то не найдено. Например, /CA /SanFrancisco должен быть найден и обработан областью, тогда как / SanFranciscoz должен 404.

вот как я быстро тестирую маршруты.

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

проблема /SanFranciscoz всегда обрабатывается страницы, но я хочу, чтобы это 404. Кроме того, если я добавлю NotFoundRoute в первую конфигурацию маршрута, все страницы области 404.

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

что я делаю не так?

вот суть, которую можно загрузить и поэкспериментировать.

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

6 ответов


ответ Dejakob правильный, DefaultRoute и NotFoundRoute были удалены в react-router 1.0.0. Я хотел бы подчеркнуть, что маршрут по умолчанию со звездочкой должно быть последним в текущем уровне иерархии, чтобы работать. В противном случае он будет соответствовать всем маршрутам, которые появляются после этого в дереве.

для react-маршрутизатора 1, 2 и 3

если вы хотите отобразить 404 и держите путь (такая же функциональность как NotFoundRoute)

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

если вы хотите отобразить страницу 404, но изменить url (та же функциональность, что и DefaultRoute)

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

пример с несколькими уровнями:

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

для react-router 4

держите путь

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

перенаправление на другой маршрут (изменить url)

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

в более новых версиях react-router вы хотите оберните маршруты в коммутатор который отображает только первый сопоставленный компонент. В противном случае вы увидите несколько компонентов.

например:

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')
);

в новой версии React Router (теперь используется 2.0.1) вы можете использовать звездочку в качестве пути для маршрутизации всех "других путей".

Так это будет выглядеть так:

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

По словам документация, маршрут был найдено, хотя ресурса не было.

Примечание: это не предназначено для использования, когда ресурс не найден. Существует разница между маршрутизатором, не находящим согласованный путь, и допустимым URL-адресом, который приводит к тому, что ресурс не найден. Url courses / 123 является допустимым url-адресом и приводит к совпадению маршрута, поэтому он был "найден" в отношении маршрутизации. Затем, если мы получим некоторые данные и обнаружим, что курс 123 не существует, мы не хотим переходить на новый маршрут. Так же, как на сервере, вы идете вперед и служите url, но визуализируете другой пользовательский интерфейс (и используете другой код состояния). Вы никогда не должны пытаться перехода к NotFoundRoute.

таким образом, вы всегда можете добавить строку в Router.run() до React.render() чтобы проверить, является ли ресурс допустимым. Просто передайте prop компоненту или переопределите Handler компонент с пользовательский чтобы показать процесс.


Я просто быстро взглянул на ваш пример, но если я понял его правильно, вы пытаетесь добавить 404 маршрута к динамическим сегментам. У меня была такая же проблема пару дней назад, нашел #458 и #1103 и закончил с ручной проверкой в функции рендеринга:

if (!place) return <NotFound />;

надеюсь, что помогает!


этот ответ предназначен для react-router-4. Вы можете обернуть все маршруты в Switch block, который функционирует так же, как выражение switch-case, и отображает компонент с первым согласованным маршрутом. ЭГ)

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

при использовании exact

без точной:

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

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

С точностью:

<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/
*/}

теперь, если вы принимаете параметры маршрутизации, и если это окажется неправильным, вы можете обработать его в самом целевом компоненте. ЭГ)

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

сейчас в наследуются profilepage.js

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

для более подробной информации вы можете пройти через этот код:

App.js

наследуются profilepage.js