In a React app with a parent and child elements, I want to achieve the following when navigating to /Parent/Child:
- I want
Childto be rendered on a new page. - I want to avoid defining a route for
/Parent/Childinindex.js(the topmost file).
Currently, in the following code (see it live), when navigating to /Parent/Child, both parent and child are rendered, thus breaking requirement #1. The reason is that <Route path='/Parent' component={Parent} /> doesn't have the exact attribute.
However, making it <Route exact path='/Parent' component={Parent} /> won't work as well, since Child won't be rendered at all (see it live), which I understand why.
An optional solution is to add /Parent/Child route in index.js (and also get rid of the Route in Parent, see it live), but it breaks requirement #2.
So, is it possible to achieve both requirements? if so, how?
- React version is 17, react-router-dom version is 5.
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import Parent from './Parent';
import { BrowserRouter as Router, Switch, Route, Redirect } from 'react-router-dom'
ReactDOM.render(
<React.StrictMode>
<Router>
<Switch>
<Route path='/Parent' component={Parent} />
</Switch>
<Redirect from='/' to="/Parent" />
</Router>
</React.StrictMode >,
document.getElementById('root')
);
Parent.js
import Child from './Child';
import { Route, useRouteMatch, useHistory } from 'react-router-dom'
function Parent() {
const history = useHistory();
const match = useRouteMatch();
return (
<div>
<Route path={`${match.path}/Child`} component={Child} />
<h1>Parent</h1>
<a target="_blank" onClick={() => history.push(`${match.path}/Child`)}>Navigate To Child</a>
</div>
);
}
export default Parent;
Child.js
import BackButton from './BackButton';
function Child() {
return (
<div>
<h1>Child</h1>
<BackButton>Go Back</BackButton>
</div>
);
}
export default Child;
BackButton.js
import { useHistory } from 'react-router-dom'
function BackButton({ children }) {
let history = useHistory()
return (
<button type="button" onClick={() => history.goBack()}>
{children}
</button>
)
}
export default BackButton;