Reputation: 38
I am using react routing for navigation among pages. This navigation having child link, Parent Link 1 Parent Link 2 a. parent1/child link 1 b. parent1/child link 2
a. parent2/child link 1 b. parent2/child link 2 c. parent2/child link 3
How to implement this navigation in react-router. Please see the attached image with this post to get clear understanding on my query.
Upvotes: 1
Views: 5993
Reputation: 2021
class App extends Component {
render() {
return (
<Router>
<div style={{width: 1000, margin: '0 auto'}}>
<ul>
<li><Link to='/'>Home</Link></li>
<li><Link to='/topics'>Topics</Link></li>
</ul>
<hr />
<Route exact path='/' component={Home} />
<Route path='/topics' component={Topics} />
</div>
</Router>
)
}
}
At this point, ” takes in a path and a component. When your app’s current location matches the path, the component will be rendered. When it doesn’t, Route will render null.”
function Topics () {
return (
<div>
<h1>Topics</h1>
<ul>
{topics.map(({ name, id }) => (
<li key={id}>
<Link to={`/topics/${id}`}>{name}</Link>
</li>
))}
</ul>
<hr />
<Route path={`/topics/:topicId`} component={Topic}/>
</div>
)
}
when we go to /topics, the Topic component is rendered. Topics then renders a navbar and a new Route which will match for any of the Links in the navbar we just rendered (since the Links are linking to /topics/${id} and the Route is matching for /topics/:topicId). This means that if we click on any of the Links in the Topics component.
It’s important to note that just because we matched another Route component, that doesn’t mean the previous Routes that matched aren’t still rendered. This is what confuses a lot of people. Remember, think of Route as rendering another component or null. The same way you think of nesting normal components in React can apply directly to nesting Routes.
At this point we’re progressing along nicely. What if, for some reason, another member of your team who wasn’t familiar with React Router decided to change /topics to /concepts? They’d probably head over to the main App component and change the Route
// <Route path='/topics' component={Topics} />
<Route path='/concepts' component={Topics} />
The problem is, this totally breaks the app. Inside of the Topics component we’re assuming that the path begins with /topics but now it’s been changed to /concepts. What we need is a way for the Topics component to receive whatever the initial path as a prop. That way, regardless of if someone changes the parent Route, it’ll always just work. Good news for us is React Router does exactly this. Each time a component is rendered with React Router, that component is passed three props - location, match, and history. The one we care about is match. match is going to contain information about how the Route was matches (exactly what we need). Specifically, it has two properties we need, path and url. These are very similar, this is how the docs describe them -
path - The path pattern used to match. Useful for building nested Routes
url - The matched portion of the URL. Useful for building nested Links
Assume we were using an app that had nested route’s and the current URL was /topics/react-router/url-parameters.
If we were to log match.path and match.url in the most nested component, here’s what we would get.
render() {
const { match } = this.props // coming from React Router.
console.log(match.path) // /topics/:topicId/:subId
console.log(match.url) // /topics/react-router/url-parameters
return ...
}
Notice that path is including the URL parameters and url is just the full URL. This is why one is used for Links and the other used for Routes.
When you’re creating a nested link, you don’t want to use URL paramters. You want the user to literally go to /topics/react-router/url-parameters. That’s why match.url is better for nested Links. However, when you’re matching certain patters with Route, you want to include the URL parameters - that’s why match.path is used for nested Routes.
Upvotes: 1