React Router V6

The guide to routing within react

Routing Libraries create experiences

You may be familiar with websites having multiple pages which are interconnected and allows users to navigate to different areas of your website. Naturally, when we want to add a new page to our website, we can just create a new HTML file and link it to other pages using the anchor tag ( <a></a>). Additionally, other pages can then link page to this newly created page with the same anchor tag.

This doesn't quite work the same when we are using something like react as something like react results in a single page application (SPA) -- an application that only has one HTML file. So the question then becomes how do we simulate a multiple-page experience within a SPA?

We'll be exploring the answer to this question in today's blog and seeing how we can accomplish something like this using a routing library such as react-router.

How do we get react-router working?

To install react-router, we want to install the package react-router-dom using npm or yarn. Here we are going to be using npm:

npm install react-router-dom

Getting Setup: The Basics

Now that this is installed we need to configure our application so that it's ready to properly handle routing. In our index.js file we want to import BrowserRouter from react-router-dom. We want to import this as router and wrap it with this component. This is being done so that all the components that are a child of App will have the ability to trigger a route change. Your index.js file should look something like this:


import {BrowserRouter as Router} from "react-router-dom";
import ReactDom from "react-dom";
import App "./App";

ReactDom.render(
    <React.StrictMode>
        <Router>
            <App />
        </Router>
    </React.StrictMode>
);

We next need to go to our App.js file or anywhere within our application we want to add route changes. Within this component, we specify that we are going to add specific routes by using Routes component that we import from react-router-dom. We additionally need to import the route component from react-router-dom. This looks something like this:

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

The Routes component is responsible for holding the specific route while the Route component is responsible for declaring and rendering the specified component linked to the route. In other words, Routes is like a phone book that holds a bunch of names and numbers while the route is an individual name that is connected to a specific phone number.

We can better visualize this by creating a simple navigation bar.

import {Routes, Route} from "react-router-dom"
import Home from "./Home"
import About from "./About"
import Contact from "./Contact"


const App = () => {
    return (

        <div className="App">
            <Navbar />

            <Routes>
                <Route path="/" element={<Home />} />
                <Route path="/About" element={<About />} />
                <Route path="/Contact" element={<Contact />} />
            </Routes>
        </div>
    );
}

export default App

As we can see Route is a child of Routes(a wrapper element that holds an individual route). Additionally, a route element can only ever be inside of the Routes wrapper component.

The route element has a few attributes:

  1. path -> Responsible for specifying the route
  2. element -> responsible for rendering the corresponding element

Therefore, saying <Route path="/About" element={<About />}/> means that when we navigate to /About we should render the about component. The same goes for /Contact, we should render the Contact component.

Navigating

We don't want to be typing are specific routes into the URL every time we want to navigate to a different page -- it's time-consuming and your end-user may not know what pages exist on your website. So we need a way to add functional links to our navigation bar. Normally in regular HTML, we can use the anchor tag (<a></a>) to add links to our page. While this is still possible to do within react, it is not really recommended as this triggers a page refresh -- negates the benefits of a single page application.

Luckily, react-router-dom comes with Link and NavLink components that we can import into our component where we want to add links. We do this by:

import {Link, NavLink} from "react-router-dom"

Now it's just a matter of using it in our component. It works just the same as the anchor tag, however, instead of an href property, we have a to property. It looks something like this:

<Link to="/About" ><p>About Page</p></Link>

So now every time the About Page text is clicked by the user, they will be navigated to the about page.

NavLink works just the same as link but it has an additional active property that can let us know if the current link is active. It adds an active class to the element which we can use to style in CSS.

Dynamic Routes

We use dynamic routes when we want to create a page for a component that we currently do not have the information for -- We know the layout of the page but the information needed to populate the page is not currently available. This may be due to us needing to get the information from a backend API. For example, let's look at a car company; This company may have different versions of their popular car model A. We as the developer for the website may not know how many versions of Model A exist, so instead of manually creating a page for the different versions of Model A, we can do it dynamically.

We can get a list of the different versions of modal A and then create a specific page for those versions. This allows us to always have the most up-to-date version of the website regarding the version of Model A.

We create a dynamic route in react using /: followed by the name of the variable for the route. It looks something like this

<Route path="/Model_A/:Version" />

Now any route that is after Model_A can be created and be a valid route.

In addition, we can get the route name from the URL using the params element. In our new page, we import the params element from react-router-dom and then we can destructure that variable to get the name of the page that is created. It looks something like this:

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

const Example = () =>{
    const {Version} = useParams();
}

We can then use this variable to do whatever we want really; If we need to make an API call that is dependent on this variable or we just need to display it, we can do that.

Miscellaneous things

Just wrapping up here, we have a few miscellaneous concepts to cover here.

We can also create navigation using the navigate hook by importing useNavigate from react-router-dom. We set up a variable and set it equal to the useNavigate hook.

const navigate = useNavigate()

Now navigate is a function we can call and pass the routes as the argument which navigates us to a specific route.

navigate("/About")

The above will take us to the About page.

We can also create a back button using this method. Instead of passing in a route, we can pass in -1 which takes us back 1 page. Now you might be wondering what happens if we pass in -3? This will take us back 3 pages. This can happen because as we navigate through our app a history stack is being built and so the navigate function is just looking at the history stack to determine what page to go back to. The back button function looks something like this:

navigate(-1)

Conclusion

Now looking at this, there's a lot more that you can do with react-router that we haven't touched on here. The documentation for react-router describes all the features in detail and I've linked it down below. Some of you may have already been using an older version of react-router, V5. There are breaking changes between version 5 and version 6 and the documentation describes how to properly upgrade so that those changes are fixed.

Alright, here is a challenge for you -> build out an application that has a functional navigation menu with the ability to have a back button within the app.

hope you found this useful, don't forget to smash the like button catch you in the next one

✌️