React Router v4 global не соответствует вложенным маршрутным дочерним элементам

Как я могу перенаправить пользователя на компонент NoMatch, когда у меня есть вложенные маршруты в React Router V4?

Вот мой код:

import React from 'react';
import ReactDOM from 'react-dom';
import injectTapEventPlugin from 'react-tap-event-plugin';
injectTapEventPlugin();

import {
    BrowserRouter as Router,
    Route,
    Switch
}
from 'react-router-dom';
import Website from './website/Website';

const Register = ({ match}) => {
    return (
        <div>
            <Route exact path={match.url} render={() => {return <h1>Register</h1>} } />
            <Route path={`${match.url}/detail`} render={()=>{return <h1>Register Detail</h1>}} />
        </div>
    )
}

const App = () => (
    <Router>
        <Switch>
                <Route exact path="/" render={() =>  {return <h1>Home</h1> }} />
                <Route path="/register" component={Register} />
                <Route component={() => {return <h1>Not found!</h1>}} />
        </Switch>
    </Router>
);

ReactDOM.render(
    <App/>, document.getElementById('root'));

Как видите, под регистром есть маршрут NoMatch, но я не хочу использовать такое же сопоставление маршрутов в моем регистре дочернего компонента. Таким образом, если я захожу в / зарегистрироваться / незарегистрированную страницу, страница просто отображается пустой, потому что не входит в NoMatch Route.

Как я могу сопоставить глобальный NoMatch без указания этого на моем дочернем маршруте? Я не хочу передавать эту ответственность дочерним компонентам.

Благодарю.

2 ответа

У меня та же проблема с Switch, так как ниже всегда будет отображаться мой компонент NoMatch, если я не захожу в / a

<Router history={history}>
  <Switch>
    <Route path='/a' component={A} />
    <Switch>
      <Route path='/b' component={B} />
      <Route path='/b/:id' component={C} />
    </Switch>
    <Route path="*" component={NoMatch}/>
  </Switch>
</Router>

Тем не менее, он будет работать, как и ожидалось, если вы поместите NoMatch во вложенный Switch следующим образом:

<Router history={history}>
  <Switch>
    <Route path='/a' component={A} />
    <Switch>
      <Route path='/b' component={B} />
      <Route path='/b/:id' component={C} />
      <Route path="*" component={NoMatch}/>  
    </Switch>
  </Switch>
</Router>

Даже если это "решение" проблемы, это не то, что вам нужно, поскольку второй коммутатор находится в другом файле, как и первый маршрут.

Таким образом, по мере роста приложения и появления новых маршрутов в разных файлах вы никогда не знаете, где вам нужно поместить маршрут NoMatch, чтобы он работал должным образом.

Нашли ли вы другое решение этой проблемы?

Что вы можете сделать, это определить все возможные пути в вашем корневом приложении. Поэтому адаптируйте компонент приложения, используя дополнительный шаблон, следующим образом:

const App = () => (
    <Router>
        <Switch>
                <Route exact path="/" render={() =>  {return <h1>Home</h1> }} />
                <Route path="/register/(detail)?" exact component={Register} />
                <Route component={() => {return <h1>Not found!</h1>}} />
        </Switch>
    </Router>
);
Другие вопросы по тегам