We have been talked about how the old website works. Now let's recall about it again to emphasize why we need a library call React Router.

The old website

Back in the day, when we clicked on a link, we would go back to the server, ask for a new HTML page and that server would send back a response that contain HTML, CSS and JavaScript. In modern world, things are different. We request the page then all the navigation happens within our website. We don't need to talk to the server anymore!

The JS file or our library (React) allows us to manipulate the DOM. Now, our servers can focus on sending data instead of focusing on what view to render, what html page to send. We can just make API requests and get JSON data back, which is really convinient.

It makes changing the DOM or users interacting with your website faster because it doesn't have to go back and forth to communicate.

Routing

Don't you notice that, the app we have been done for a while only have one Home component. Which pretty much comprise our entire app.

But what if we had multiple page components, like an ProductPage component or ProfilePage component that needed to be rendered depending on what you URL the user was at? This is what routing try to solve, and the routing library we use for our app is called React Router.

React Router is the de facto standard routing library for React. When you need to navigate through a React application with multiple views, you'll need a router to manage the URLs. React Router takes care of that, keeping your application UI and the URL in sync.

React is a popular library for creating single-page applications (SPAs) that are rendered on the client side. An SPA might have multiple views (aka pages), and unlike conventional multi-page apps, navigating through these views shouldn't result in the entire page being reloaded. Instead, we want the views to be rendered inline within the current page. The following features are expected in an SPA:

We're going to take a simple CoderNews with the routing as example.

The structure of the simple CoderNews look like this:

|-node_modules
|-public
|-src
    |-pages
        |-HomePage.js
        |-Products.js
        |-DetailPage.js
    |-App.js
    |-App.css
    |-index.js
|-package.json
|-package-lock.json

You can install React Router using the command: npm install react-router-dom

BrowserRouter

Import BrowserRouter from react-router-dom In index.js

import {BrowserRouter as Router} from "react-router-dom"

ReactDOM.render(
  <Router>
    <App />
  </Router>,
  document.getElementById('root')
);

Route

In App.js:

import {  Route} from "react-router-dom"

function App() {
  return (
  <>
    <Route exact  path="/" component={Homepage}/>
    <Route path="/products" component={Products}/>
  </>
  );
}

Switch

In App.js:

import {  Route, Switch} from "react-router-dom"

function App() {
  return (
      <Switch>
        <Route exact  path="/" component={Homepage}/>
        <Route path="/products" component={Products}/>
      </Switch>
  );
}

In React router, we have two main way to navigate. That is Link component and history.push

Link component

For example, in our HomePage.js:

import React from "react"
import {Link} from "react-router-dom"

const HomePage = ()=>{
    return (
    <div>
        <h1>This is homepage</h1>
        <Link to="/products">Go to Products page</Link>
    </div>
    
    )
}

export default HomePage

You might ask why don't we use a tag?

history.push()

Now let me introduce you a hook in React router, the useHistory

The useHistory hook gives you access to the history instance that you may use to navigate.

The history object allows you to manage and handle the browser history inside your views or components.

Example:

import React from "react"
import {Link, useHistory} from "react-router-dom"

const HomePage = ()=>{
    const history = useHistory()
    const handlePush =()=>{
        history.push("/products")
    }
    return (
    <div>
        <h1>This is homepage</h1>
        <Link to="/products">Go to Products page</Link>
        <button onClick={handlePush}>Another way to Products page</button>
    </div>
    
    )
}

export default HomePage

Try the code above, and now we have another way to navigate our app.

We have learn the first hook useHistory that is use for navigation. Now we're going to learn a new hook called useParams()

First we need to know what is params:

In App.js:

import React form "react"
import {  Route, Switch} from "react-router-dom"
import Homepage from './pages/Homepage';
import ProductPage from './pages/Products';
import DetailPage from './pages/DetailPage'

function App() {
  return (
      <Switch>
        <Route exact  path="/" component={Homepage}/>
        <Route exact path="/products" component={ProductPage}/>
        <Route exact path="/products/:productId" component={DetailPage}/>
      </Switch>
  );
}

in DetailPage:

import React from 'react'
import { useParams } from 'react-router'

const DetailPage = () => {
    const params = useParams() //use the hook and assign its value to params variable
    const {productId} = params
    console.log("productId",productId)
    return (
        <div>
            This is detail Page
        </div>
    )
}

export default DetailPage

Then try to access the URL: http://localhosl:3000/products/123 then check the console on your browser to see what we get line 7

This is how we can access to that dynamic value from the URL, by using React router hook useParams

A little bit further, why we even care about that productId part? Because, as the name says, DetailPage is a page that will display all the information of that single product. To be able to find a single product data, we need its id to send a GET request to backend.

We keep using the News api to play around with routing

Requirements:

Bonus: