Skip to content

Commit 8157484

Browse files
committed
Detecting Dynamic Routes using <Route to="/:id" /> & Passing Route
Parameters
1 parent b142ca1 commit 8157484

3 files changed

Lines changed: 72 additions & 66 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,4 @@ Required Dependency: **`npm i --save axios`** | **[`axios` DOCS](https://github.
136136
8. The `withRouter()` HOC & Route Props: [Commit Details](https://github.com/Ch-sriram/react/commit/f89ef0cbf6a77288b36bf0542c5b8dee95ca67b7)
137137
9. Absolute vs. Relative Paths: [Commit Details](https://github.com/Ch-sriram/react/commit/f1cb5c5df16561fba48a0731e17b32e204822a60)
138138
10. Styling the Active Route using `<NavLink to="<route>" exact activeClassName="<class-name>" activeStyle={<style-object>}/>` Component: [Commit Details](https://github.com/Ch-sriram/react/commit/d226ec6c421c88c5e6818e2c85e531661d48582d)
139+
11. Detecting Dynamic Routes using `<Route to="/:id" />` & Passing Route Parameters: [Commit Details]()

http-ajax-routing/src/containers/Blog/Blog.js

Lines changed: 37 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22
import React, { Component } from "react";
33
import { Route, NavLink } from 'react-router-dom';
44

5-
// STYLING
5+
// STYLING IMPORTS
66
import "./Blog.css";
77

88
// CUSTOM COMPONENTS
99
import Posts from '../../containers/Blog/Posts/Posts';
1010
import NewPost from './NewPost/NewPost';
11+
import FullPost from './FullPost/FullPost';
1112

1213
class Blog extends Component {
1314
componentDidMount() {
@@ -18,71 +19,15 @@ class Blog extends Component {
1819
return (
1920
<div className="Blog">
2021
<header>
21-
{
22-
/**
23-
* Using <NavLink /> Component, we can use some extra
24-
* props which allow us to define some styling for the
25-
* active link, i.e., the link that's actually clicked.
26-
*
27-
* Now, when we can style the links in Blog.css file,
28-
* for their respective class/id/element along with the
29-
* .active class, to change the styling when the link
30-
* is actually active, i.e., the contents of the route
31-
* related to that link are being displayed on the
32-
* page/view.
33-
*
34-
* Now, when we click on the "New Post" link, even the
35-
* "Home" link is styled as if it is having the .active
36-
* class, but it is actually having the .active class,
37-
* and that's because the <NavLink /> applies the
38-
* .active class to every link that has the route
39-
* prefixed with the path "/". We need to get rid of
40-
* this behaviour by giving the `exact` prop to the
41-
* <NavLink /> component related to "Home" Link as
42-
* shown below.
43-
*/
44-
}
4522
<nav>
4623
<ul>
47-
<li><NavLink
48-
to="/"
49-
exact
50-
/**
51-
* Sometimes, we might not want the default
52-
* class, which is .active, to be the class name,
53-
* when we click the link. We might want to have
54-
* our own class name applied to the active link,
55-
* and that can be done as shown below:
56-
*/
24+
<li><NavLink to="/" exact
5725
activeClassName="my-active"
58-
/**
59-
* Because of the prop above, we have to add
60-
* styling for the "Home" route separately to
61-
* style it when it is active i.e., when the "/"
62-
* route (i.e., "Home") is active, the .my-active
63-
* class is the one attached to the respective
64-
* <NavLink /> Component for the "Home" link, and
65-
* so, we style using the .my-active class inside
66-
* the Blog.css file.
67-
*/
68-
69-
/**
70-
* We can also directly style the <NavLink />
71-
* directly in here, using inline styling, using
72-
* the activeStyle prop as shown below:
73-
*/
7426
activeStyle={{
7527
color: '#FA923F',
7628
textDecoration: 'underline'
7729
}}
7830
>Home</NavLink></li>
79-
{
80-
/**
81-
* Here, we don't need the `exact` prop as, there
82-
* is no other link that prefixes '/new-post'
83-
* route.
84-
*/
85-
}
8631
<li><NavLink to={{
8732
pathname: '/new-post',
8833
hash: '#submit',
@@ -91,8 +36,42 @@ class Blog extends Component {
9136
</ul>
9237
</nav>
9338
</header>
39+
{
40+
/**
41+
* For every <Post /> Component we click on, we should
42+
* be able to render the entire <FullPost /> Component
43+
* related to the clicked <Post />.
44+
*
45+
* Which is why, we set a specific Route for the
46+
* <FullPost /> to be loaded whenever the path matches
47+
* some kind of an `id`, which in this case is `post.id`.
48+
* handled inside the <Posts /> Component.
49+
*
50+
* Therefore, we add the route for "/:id", which is
51+
* telling to the react-router that this route is a
52+
* dynamic route. Anything that's prefixed with "/" and
53+
* has some string after it, will render the component
54+
* mentioned respectively.
55+
*
56+
* But that would also make the "/new-post" route render
57+
* the component we mention inside the route for "/:id"
58+
* because now, "/new-post" is also a route which
59+
* matches the rule of the route mentioned as "/:id".
60+
*
61+
* To avoid this confusion, we can render the <Route />
62+
* for the "/new-post" path before the <Route /> for the
63+
* "/:id" path, as shown below.
64+
*/
65+
}
9466
<Route path="/" exact component={Posts} />
9567
<Route path="/new-post" component={NewPost} />
68+
<Route path="/:id" exact component={FullPost} />
69+
70+
{// The following ordering of Routes won't work properly
71+
// <Route path="/" exact component={Posts} />
72+
// <Route path="/:id" exact component={FullPost} />
73+
// <Route path="/new-post" component={NewPost} />
74+
}
9675
</div>
9776
);
9877
}

http-ajax-routing/src/containers/Blog/Posts/Posts.js

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// LIBRARY IMPORTS
22
import React, { Component } from 'react';
33
import axios from '../../../axios'; // this is our own axiosInstance that we created earlier inside axios.js
4+
import { Link } from 'react-router-dom';
45

56
// STYLE IMPORTS
67
import './Posts.css';
@@ -39,14 +40,27 @@ class Posts extends Component {
3940
let posts = <p style={{ textAlign: "center" }}>Something Went Wrong!</p>;
4041

4142
if (!this.state.error) {
42-
posts = this.state.posts.map((post) => (
43-
<Post
44-
key={post.id}
45-
title={post.title}
46-
author={post.author}
47-
clicked={() => this.postSelectedHandler(post.id)}
48-
// {...this.props}
49-
/>
43+
posts = this.state.posts.map(post => (
44+
/**
45+
* We will make every <Post /> Component a link, so that
46+
* whenever it is clicked, we can use our react-router
47+
* to route to a specific route as mentioned inside the
48+
* `to` prop inside the <Link /> Component seen below.
49+
*
50+
* We also add the `key` prop to the <Link /> component
51+
* now because it is the outermost component which is
52+
* being generated as a list of components to be
53+
* rendered onto the view, and so, every sequence of
54+
* similar components needs to have a unique `key` prop
55+
* according to rules in React.
56+
*/
57+
<Link to={`/${post.id}`} key={post.id}>
58+
<Post
59+
title={post.title}
60+
author={post.author}
61+
clicked={() => this.postSelectedHandler(post.id)}
62+
/>
63+
</Link>
5064
));
5165
}
5266

@@ -55,3 +69,15 @@ class Posts extends Component {
5569
};
5670

5771
export default Posts;
72+
73+
/**
74+
* Now whenever we click on any <Post /> generated at the "/"
75+
* (Home) route, we can actually see that the related ID to that
76+
* <Post /> (i.e., `post.id`) is appended as a route in the
77+
* address bar.
78+
*
79+
* Although, we just need to use that ID inside the route
80+
* mentioned in the address bar and then display the <FullPost />
81+
* related to the <Post /> we clicked (which can be done by
82+
* extracting the route parameters).
83+
*/

0 commit comments

Comments
 (0)