Project 40 of 100 - Practice Using React Router by Creating a Static Cryptocurrency Database
Tags: react, javascript, 100daysofcode, blockchain
Published: 2021-01-29 08:16:22

*Hey! I'm on a mission to make 100 React.js projects ending March 8th. Please follow my dev.to profile or my [twitter](https://www.twitter.com/jwhubert91) for updates and feel free to reach out if you have questions. Thanks for your support!*

Link to today's deployed app: [Link](https://100-react-projects-day-40-react-router-crypto.netlify.app/)
Link to the repo: [github](https://github.com/jwhubert91/100daysofreact/tree/master/day-40-react-router-crypto)

If you're building React applications, you're almost always going to need to build out some routes so that you have an easy way to display separate pages. The standard these days is to use the `react-router-dom` npm package.

This project builds on [my project from yesterday](https://dev.to/jwhubert91/project-39-of-100-build-a-basic-blog-ui-with-react-antdesign-and-lodash-2mhe) for a simple blog UI using Ant Design and Lodash. If you want to build this from scratch that's the best place to start.

##React Router
React Router is a tool that creates artificial routing to components in your app. Why artificial? Well the url routes are real, but React creates single-page-applications, so the pages themselves are just you telling React "only show this component when the URL is at this address".

In this project I used several parts of the `react-router-dom` package, and I had to actually read the (fantastic) docs for it because the tutorial I'm following is quite old and uses a deprecated routing system.

First, you'll need to import the package into your file. I did this in my app component where I display all of the article previews. Here is how you import the package:

```
import {
  BrowserRouter as Router,
  Switch,
  Route
} from "react-router-dom";
```

You'll notice that the import object makes use of [aliasing](https://medium.com/dailyjs/using-import-aliases-in-javascript-a0b46237601c) to rename the un-sexy "BrowserRouter" to just "Router".

To use the Router in your application, first open up a JSX element and create the Router component, I filled mine with a switch, which tells React Router to show the component with the first matching path. For this reason, we list our index page at the bottom so it matches last and is thus the default.

```
const App = () => {
  return (
    <div className="app_container">
      <Router>
        <Switch>
          <Route path='/post/:id'>
            <Post />
          </Route>
          <Route path='/'>
            <Posts />
          </Route>
        </Switch>
      </Router>
    </div>
  );
}
```

You can see here that we made use of all three of the components brought in from `browser-router-dom`. The Router lets React know that it's a router and to behave accordingly, the Switch tells the Router that it should show the component with the first matching path defined in the `path` attribute. The Route elements are where you define the path you want to route to. Child elements are then given to the Route elements to tell the Switch which component you want it to show.

For the index page at path '/', we show the Posts component. This shows a little list of all of the possible cryptocurrencies we have data on like so:

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

In this component we import the data from our mock api, a JSON file with an array of objects filled with info about cryptocurrencies. We map through each object in the mock api array and display it on the screen using our `PostSnippet` component. This was covered in yesterday's project so I won't go over it again, but have a look at the github to check out the JSX for that one. You can also see I set up a navbar using Ant Design's pre-built <PageHeader /> component that uses a very cool `title` attribute.

##Displaying the Correct Component
At this point I was at a loss. The tutorial I was following used Reach Router which is sort of old and I believe was folded into the React Router project, so I was on my own. To actually go to the page referenced by the `:id` variable in the post path, we need to somehow get that when we're *inside* the post. How can we do this dynamically? We could pass down props, but what if there are ten thousand cryptos I have articles about? 

Enter the React Router `useParams()` method. After importing the `useParams` object from the `react-router-dom` package, in the Post component we can get the actual unique ID used for this page using the method like so:

```
import {useParams} from 'react-router-dom';
...

const postId = useParams().id;
```

This searches through the parameters in the actual URL to find one called `id`. We can then use this ID to search through our mock cryptocurrency API and find the correct article, without passing that info down from props. I then use the `useState` and `useEffect` React hooks to set the Post component's state whenever there is a change in that postId variable, so we have content from the API. Here is what that component looks like for me:

```
import React, {useState,useEffect} from 'react';
import {Card,PageHeader} from 'antd';
import {useParams} from 'react-router-dom';
import api from '../mock_api';

const Post = (props) => {
  
  const postId = useParams().id;
  const [title,setTitle] = useState('');
  const [content,setContent] = useState('');
  const [imageUrl,setImageUrl] = useState('');

  useEffect(() => {
    let post = api[postId];
    setTitle(post.coin);
    setContent(post.description);
  },[postId])

  return (
    <div className="post_container">
      <div className="page_header_container">
        <PageHeader
          style={{
            border: '1px solid rgb(235,237,240)'
          }}
          title={title}
        />
      </div>
      <div className="post_content_container">
        <Card style={{marginTop: '20px'}} >
          {
            content.split('\n').map((textParagraph,idx) => {
              return <p key={idx}>{textParagraph}</p>
            })
          }
        </Card>
      </div>
    </div>
  )
}

export default Post;
```

You can see we also use the Card and PageHeader components from Ant Design here, which I covered in yesterday's tutorial, and a map method to split the description into readable paragraphs whenever there is a pagebreak `\n` encoded into the text.

In light of all of this week's hype around certain stocks and crypto, I thought it would be fun to create a little database on the top 5 coindesk cryptocurrencies in their honor.

Look out for dynamic data tomorrow! No more mock APIs!