React-Router: Ні маршруту не знайдено?


132

Розглянемо наступне:

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 завжди обробляється сторінкою Area, але я хочу, щоб це було 404. Також, якщо я додати NotFoundRoute до першої конфігурації маршруту, всі сторінки 404.

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

Що я роблю неправильно?

Ось суть, яку можна завантажити та експериментувати.

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


Для подальшого ознайомлення з людьми, які стикаються з цим питанням, окрім правильної відповіді нижче, прочитайте цю статтю . Я натрапив на це раніше і, думаю, ця людина це чудово пояснює.
Димитріс Дамілос

Відповіді:


248

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>

Порядок має значення!


якщо у вас є програма для скорочення, як це зробити: <Redirect from='*' to='/home' />у цьому синтаксисі:const routes = { component: Main, childRoutes: [ { path: '/', component: Home }, ], indexRoute: { component: Main, }, };
tatsu

1
якщо ви хочете встановити реквізит для 404-Compontent, використовуйте цей код: <Route render={(props)=> <MyComponent myProp={someVar} {...props} />} />
Marco Weber

Що з 500 сторінок? Як сторінка, яка повинна завантажуватися, але API дає помилку. Як показати це замість сторінки, яка не вдалася під час утримання маршруту?
PixMach

<Перенаправлення на = "/ 404" /> викликає перевищення максимальної глибини оновлення на реакторі-маршрутизаторі 5.0.0. Навіть якщо сторінка 404 виходить, вона переспрямовується.
MiguelSlv

4
Мені не подобається використовувати переадресацію, оскільки вона приховує проблемну URL-адресу від користувача. Також потрібно двічі натиснути назад, щоб повернутися до попередньої сторінки.
sdgfsdh

39

У новіших версіях реактор-маршрутизатора ви хочете загортати маршрути в комутатор, який відображає лише перший відповідний компонент. В іншому випадку ви побачите кілька компонентів, що відображаються.

Наприклад:

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

12
Не потрібно включати path="*"в маршрут NotFound. Якщо пропустити path, маршрут завжди збігатиметься.
chipit24

1
Для людей, які приходять пізно, @ chipit24 має рацію, щоб уникнути плутанини, просто пропустіть pathцілком невідомі маршрути
Altair312

14

З новою версією 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>

10

Ця відповідь призначена для react-router-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


6

Згідно з документацією , маршрут був знайдений, хоча ресурсу не було.

Примітка . Це не призначене для використання, коли ресурс не знайдений. Існує різниця між тим, що маршрутизатор не знайде відповідний шлях, і дійсною URL-адресою, що призводить до того, що ресурс не знайдений. Курси url / 123 є дійсним URL-адресою і призводить до узгодженого маршруту, тому його "знайшли", що стосується маршрутизації. Потім, якщо ми отримаємо деякі дані і виявимо, що курс 123 не існує, ми не хочемо переходити на новий маршрут. Як і на сервері, ви йдете вперед і обслуговуєте URL, але надаєте інший інтерфейс користувача (і використовуєте інший код статусу). Ніколи не слід намагатися перейти на NotFoundRoute.

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


дякую @brad, ви маєте рацію, вам доведеться впоратися з цим компонентом і або перекрити обробник, перш ніж router.run
4m1r

3
NotFound був застарілим github.com/reactjs/react-router/releases/tag/v1.0.0 , зараз використовую <Route path="*" to="/dest" />або <Redirect from="*" to="/dest" />як останній
підвідний

5

Я просто переглянув ваш приклад, але якщо я зрозумів це правильно, ви намагаєтеся додати 404 маршрути до динамічних сегментів. У мене був такий самий випуск пару днів тому, знайшли № 458 і № 1103 і в результаті переглянули вручну перевірку в функції візуалізації:

if (!place) return <NotFound />;

сподіваюся, що допомагає!


дякую @jorn, я думаю, ти маєш рацію, це здається адресною лише на рівні компонентів
4m1r
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.