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>
];
У меня есть шаблон приложения, набор заголовков и набор параметров с таким же обработчиком (в шаблоне приложения). Я хочу иметь возможность обслуживать 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 всегда обрабатывается на странице Area, но я хочу, чтобы она была 404. Кроме того, если я добавлю NotFoundRoute в первую конфигурацию маршрута, все страницы 404 области.
<Route handler={App} someProp="defaultProp">
<Route path="/" handler={Page} />
<NotFoundRoute handler={NotFound} />
</Route>,
Что я делаю неправильно?
Вот суть, которую можно загрузить и экспериментировать.
https://gist.github.com/adjavaherian/aa48e78279acddc25315
Ответы
Ответ 1
DefaultRoute и NotFoundRoute были удалены в реакции-маршрутизаторе 1.0.0.
Я хотел бы подчеркнуть, что маршрут по умолчанию со звездочкой должен быть последним в текущем уровне иерархии для работы. В противном случае он переопределит все другие маршруты, которые появляются после него в дереве, потому что он первый и соответствует каждому пути.
Для реагирующих маршрутизаторов 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>
Для реагирующих маршрутизаторов 4 и 5
Держи путь
<Switch>
<Route exact path="/users" component={MyComponent} />
<Route component={GenericNotFound} />
</Switch>
Перенаправить на другой маршрут (изменить URL)
<Switch>
<Route path="/users" component={MyComponent} />
<Route path="/404" component={GenericNotFound} />
<Redirect to="/404" />
</Switch>
Порядок имеет значение!
Ответ 2
В новых версиях реактивного маршрутизатора вы хотите обернуть маршруты в Switch, который отображает только первый согласованный компонент. В противном случае вы увидите несколько отображаемых компонентов.
Например:
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
С новой версией 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>
Ответ 4
Этот ответ для реакции-маршрутизатор-4. Вы можете обернуть все маршруты в блоке Switch, который функционирует так же, как выражение регистра, и отображает компонент с первым соответствующим маршрутом. например)
<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
Ответ 5
Согласно документации, маршрут был найден, хотя ресурса не было.
Примечание: это не предназначено для использования, когда ресурс не найден. Существует разница между маршрутизатором, не находящим соответствующий путь, и действительным URL, который приводит к тому, что ресурс не найден. URL-адреса курсы /123 являются допустимыми и приводят к сопоставленному маршруту, поэтому он был "найден" в отношении маршрутизации. Затем, если мы получим некоторые данные и обнаружим, что курс 123 не существует, мы не хотим переходить на новый маршрут. Как и на сервере, вы идете вперед и обслуживаете URL, но визуализируете другой интерфейс (и используете другой код состояния). Вы никогда не должны пытаться перейти на NotFoundRoute.
Таким образом, вы всегда можете добавить строку в Router.run()
перед React.render()
чтобы проверить, является ли ресурс действительным. Просто передайте опору компоненту или переопределите компонент Handler
с помощью пользовательского, чтобы отобразить представление NotFound.
Ответ 6
Я просто быстро посмотрел на ваш пример, но если бы я понял это правильно, вы пытаетесь добавить 404 маршрута в динамические сегменты. У меня была такая же проблема пару дней назад, я нашел # 458 и # 1103 и закончил с ручной проверкой внутри функции рендеринга:
if (!place) return <NotFound />;
надеюсь, что это поможет!