最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - react-router - Navigate to parent route from nested router - Stack Overflow

programmeradmin3浏览0评论

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="/" ponent={HomePage} />
        <Route path="/account" ponent={AccountDashboard} />
     </div>
 </Router>

Here is the router inside AccountDashboard:

<Router>
    <Route path="/account/password-reset" ponent={ChangePassword} />
    <Route path="/account/sign-out" ponent={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 ponent). The child router is just returning null.

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

If I add a route for '/' in the AccountDashboard router, any ponent I provide will render just fine because the router in AccountDashboard matches it, but I want to redirect to '/' within the ChangePassword ponent and show the HomePage ponent 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 ponent={Blue} />
      <Route path="/colors/green" ponent={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 ponent={Letters} />
          <Route path="/colors" ponent={Colors} />
        </div>
      </Router>
    );
  }
}

export default App;

With the above code, the app will load and display the Letters ponent. 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 ponent does not display.

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="/" ponent={HomePage} />
        <Route path="/account" ponent={AccountDashboard} />
     </div>
 </Router>

Here is the router inside AccountDashboard:

<Router>
    <Route path="/account/password-reset" ponent={ChangePassword} />
    <Route path="/account/sign-out" ponent={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 ponent). The child router is just returning null.

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

If I add a route for '/' in the AccountDashboard router, any ponent I provide will render just fine because the router in AccountDashboard matches it, but I want to redirect to '/' within the ChangePassword ponent and show the HomePage ponent 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 ponent={Blue} />
      <Route path="/colors/green" ponent={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 ponent={Letters} />
          <Route path="/colors" ponent={Colors} />
        </div>
      </Router>
    );
  }
}

export default App;

With the above code, the app will load and display the Letters ponent. 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 ponent does not display.

Share Improve this question edited Jan 16, 2019 at 5:18 asked Jan 16, 2019 at 3:28 user10746369user10746369 3
  • Are you saying that when you press the back button from a Child ponent, it is not returning to the previous page? Or that a <Link> to "/" in the Child ponent is not working either? – Gabor Szekely Commented Jan 16, 2019 at 6:10
  • 4 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 ? – butchyyyy Commented Jan 16, 2019 at 9:07
  • 1 You are pletely right. I shouldn't have two routers. Once I removed the extra Router tags from around the other child routes, everything worked like a charm. If you could post that as an answer, I would be happy to accept it. Thanks! – user10746369 Commented Jan 16, 2019 at 17:22
Add a ment  | 

1 Answer 1

Reset to default 5

@butchyyyy answered this for me in the ments 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 ponent and use the parent path within child paths.

This is what the child ponent looks like:

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

Hope this helps someone else.

发布评论

评论列表(0)

  1. 暂无评论