TIL - React Router 2: Dynamic URL Parameters
Tags: react, beginners, router, webdev
Published: 2020-08-31 18:37:10

<Route path='/:id' component={User} />

URL parameters are parameters whose values are set dynamically in a page’s URL. This allows a route to render the same component (UI) while passing that component the dynamic portion of the URL so it can change based off of it.

1. Create a `<Route>`
```javascript
 <Route path="/user-profile/:tool/:name" component={UserProfile} />
``` 
The :tool and :name parts of the path will be considered as variable parameters.

2. Set the `<Link>` to 
```javascript 
             <li>
              <Link to="/user-profile/Github/Leonor">Leonor Git</Link>
            </li>
            <li>
              <Link to="/user-profile/Github/Diana">Diana Git</Link>
            </li>
            <li>
              <Link to="/user-profile/Codesandbox/Leonor">Leonor Sandbox</Link>
            </li>
            <li>
              <Link to="/user-profile/Codesandbox/Diana">Diana Sandbox</Link>
            </li>
``` 
React Router will compare the shapes of the paths and pick the right one. 

3. Get the values of the params Object

Whenever React Router v4 renders a component, it’ll pass to that component three props, match, location, and history. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/bfuxw6pzjlzorqf2urm0.png)

* url is the actual relative path in your address bar: /Codesandbox/Diana

* path is, as its name suggests, the path of the matched route: /:tool/:name

* isExact is a boolean indicating if this is an exact match. It is true here, because the actual path has as many segments as the path attribute; if our current URL had been /Codesandbox/Diana/Surname, the route would have been activated, but isExact would be false.

* params is an object.If you unfold it, you see that, we can grab the URL parameter (id) as a property on match.params.

```javascript
const params = props.match.params;
      <h2>
        {params.name}s {params.tool} Profile
      </h2>
``` 

{% codesandbox dynamicrouter-sey4e %}


## useParams Hooks 
useParams returns an object of key/value pairs of URL parameters. Use it to access match.params of the current `<Route>`.

```javascript
const About = () => {
  const { name } = useParams()
  
return (
  // props.match.params.name
  <>
     <h1>About {name}</h1>
  </>
)
};
``` 

## Using URL parameters

In PostList.js, adds this list of fake blog posts, just below the imports:
```javascript
const allPosts = [
  { year: '2019', month: '09', title: 'React Router v5.1 released' },
  { year: '2019', month: '09', title: 'React 16.10.0 released' },
  { year: '2019', month: '10', title: 'React Conf 2019' },
  { year: '2019', month: '10', title: 'Transition of Node.js 12 to LTS' }
];
``` 

Then replace the component's content altogether:
```javascript
function PostList(props) {
  // Get the URL parameters
  const params = props.match.params;
  // Filter allPosts array: keep posts who have the
  // same month AND same year as the URL parameters
  const filteredPosts = allPosts.filter(
    post => post.year === params.year && post.month === params.month
  );
  return (
    <div>
      <h2>Posts for {params.month}/{params.year}</h2>
      {
        filteredPosts.map(post => (
          <h3>{post.title}</h3>
        ))
      }
    </div>
  );
}
```

The filter we apply on all Posts is the most interesting part. The Filter iterates over all the posts; its "criterion", i.e. the function that it's given as a paremeter, checks if each post complies with this condition: do the post's year and month match the year and month in the URL? If so, the post object is retained and will be present in filteredPosts.

Finally, we apply map on filteredPosts, in order to display the titles of the matching posts.