React Router v4 global no match to nested route childs

一笑奈何 提交于 2019-12-24 03:24:24

问题


How can I redirect the user to a NoMatch component when I have nested routes in React Router V4?

Here is my code:

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

As You can see, there is a NoMatch route below Register but I don't want to use the same Route mapping on my child component Register. In this way, if I go to /register/unregisteredmatch the page just show blank because do not enter in NoMatch Route.

How can I map a global NoMatch without specify that on my child route? I don't want to pass this responsability to the child components.

Thanks.


回答1:


I have the same problem with Switch since the following will always render my NoMatch component if I do not go to /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>

However, it will work, as expected, if you move your NoMatch inside the nested Switch like this:

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

Even if this is a 'solution' to the problem it is not what you want since the second Switch is in a different file like the first Route is as well.

So as the application grows and more routes come into play in different files you never know where you need to put the NoMatch route for it to work as expected.

Did you find any other solution to this problem?




回答2:


What you could do is define all possibly allowed routes in your root App. Therefore, adapt your App component using optional pattern as follows:

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


来源:https://stackoverflow.com/questions/43289132/react-router-v4-global-no-match-to-nested-route-childs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!