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.
-
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
1 Answer
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.