简体   繁体   中英

react-router - Navigate to parent route from nested router

I'm playing around with react-router , and I have a problem when using nested routes.

Here is my parent router:

<Router>
    <div>
        <Route exact path="/" component={HomePage} />
        <Route path="/account" component={AccountDashboard} />
     </div>
 </Router>

Here is the router inside AccountDashboard :

<Router>
    <Route path="/account/password-reset" component={ChangePassword} />
    <Route path="/account/sign-out" component={SignOut} />
</Router>

Once I navigate to either /account/password-reset or /account/sign-out , I can't seem to navigate back to the root of the parent router (to view the HomePage component). The child router is just returning null.

For example, I tried calling both props.history.push('/') and props.history.reset('/') within the ChangePassword component, but the child router returns null.

If I add a route for '/' in the AccountDashboard router, any component I provide will render just fine because the router in AccountDashboard matches it, but I want to redirect to '/' within the ChangePassword component and show the HomePage component via the parent router.

How do I navigate to a route on a parent router within a child/nested router?

Edit: I just made a basic implementation from scratch, same problem:

import React, { Component } from 'react';
import './App.css';
import { BrowserRouter as Router, Route, Link, withRouter } from "react-router-dom";

const Blue = withRouter(({ history }) => (
  <div style={{ border: "1px solid #222", width: "300px", padding: "4px", margin: "4px"}}>
    <h2>Blue Component</h2>
    <span
      style={{color: 'blue', textDecoration: 'underline'}}
      onClick={() => { history.replace('/') }}>
      Go back to Letters
    </span>
  </div>
));

const Green = withRouter(({ history }) => (
  <div style={{ border: "1px solid #222", width: "300px", padding: "4px", margin: "4px"}}>
    <h2>Green Component</h2>
    <span
      style={{color: 'blue', textDecoration: 'underline'}}
      onClick={() => { history.replace('/') }}>
      Go back to Letters
    </span>
  </div>
));

const Letters = () => (
  <div style={{ border: "1px solid #222", width: "300px", padding: "4px", margin: "4px"}}>
    <h2>Letters (Root) Component</h2>
  </div>
)
const Colors = () => (
  <Router>
    <div>
    Child Router
    <br></br>
    [ <Link to="/colors/blue">Blue</Link> ]
    [ <Link to="/colors/green">Green</Link> ]
      <Route path="/colors/blue" exact component={Blue} />
      <Route path="/colors/green" component={Green} />
    </div>
  </Router>
);

class App extends Component {
  render() {
    return (
      <Router>
        <div>
        Parent Router
        <br></br>
        [ <Link to="/">Letters</Link> ][ <Link to="/colors">Colors</Link> ]
          <Route path="/" exact component={Letters} />
          <Route path="/colors" component={Colors} />
        </div>
      </Router>
    );
  }
}

export default App;

With the above code, the app will load and display the Letters component. If you click on Colors , you'll be taken to the second router, where you can select 'Blue' or 'Green', which each have a link back to '/'. When you follow that link, the URL changes correctly to '/', but the original Letters component does not display.

@butchyyyy answered this for me in the comments but I'm answering in case someone else will find it.

he said: Is there any reason for using two Routers in your app? You should only have one router at the top level. Does this sandbox do what you want: codesandbox.io/s/8kwy5pkvm8

I have a main Navigation with a switch and one of the pages had a sub navigation.

What worked for me was to simply remove the second router component and use the parent path within child paths.

This is what the child component looks like:

const Apps = () => (
    <div className='main-container'>
    <SubNav items={subNavOptions} />
    <Route exact path='/apps' component={Applist} />
    <Route path='/apps/single-choice-lists' component={SingleChoiceLists} />
    <Route path='/apps/classification-sets' component={ClassificationSets} />
  </div>
)

Hope this helps someone else.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM