2.2.3: React Router

Learning Objectives

  1. React Router allows us to keep our app URLs in sync with components we are viewing.

  2. How implement React Router in our applications.

  3. How to control user flow with React Router.

  4. How to implement Private Routing within our applications.

Introduction

React Router is a React library that enables us to keep our app URLs in sync with components we are viewing. Prior to React Router we needed to extensively add supplementary code to our app so that our URL did update, which is fine for small single-page apps but less so when our apps gets more complex.

Scroll through the React Router homepage to become familiar with the implementation concepts that are used by this package. The implementation that follows is Rockets way of giving you routes in React quickly and without fuss.

Official Tutorial

Complete the official React Router tutorial to familiarise yourself with React Router. Once we learn the mechanics of React Router we will integrate it into our apps with Create React App.

  1. We will not be using Remix at Rocket, the other framework mentioned in the tutorial

  2. We will not be using createBrowserRouter, instead we use BrowserRouter its implementation is shown below

  3. Pay attention to how we can use nested Routes

  4. Pay attention to how the Outlet component renders out sub components

  5. Always add the "no match" case in our apps for robustness

  6. Note we need to import the React Router React Hook useParams from react-router-dom to get URL params

  7. We can skip the section on Custom Behaviour; those use cases will most likely not apply to us and we can come back to this when we need to.

React Router

Rocket advises using the following setup when developing Routing in React, this setup is straightforward and easy to understand. Read more about the implementation here.

Vital Components

BrowserRouter This tool used to update the current url path that is rendered in the browser. All of the Routes, Route, Link's and React components that are nested will be connected via React Routing, by React Router Dom.

Routes This component matches the current url to the component that should be rendered, Routes will render the component within the Route with the matching path parameter. Only one component will be rendered unless nested routes are implemented.

Route These components are used to define the component or components that will render depending on the current url path that is in the browser. If an Outlet is contained in this component, nested Route components may also be rendered onto the screen.

Outlet This component is used so that multiple path components can be rendered within a Routes Component. This makes rendering children of routes easy.

Link This component allows our users to navigate through the application such that they can visit every path and therefore every component. The links have a to prop which should match a Route's path prop.

Implementation

The implementation below is how we can develop a routing system within our React applications using the BrowserRouter, you can use the navigate hook as well as Links within the BrowserRouter.

You will need to clone this repo, to see how this application functions. Remember to install your node_modules. Notice how react-router-dom is listed as a dependency in the package.json.

Simple Example

        <BrowserRouter>
        
          <div>
            <Link to="/">Home</Link>
            <Link to="/fruits">Fruit</Link>
            <Link to="/fruits/form"> Fruit Form</Link>
            <Link to="/fruits/list">Fruit Lists</Link>
          </div>
          
          <Routes>
          
            <Route path="/" element={<Home />} />
            
            <Route path="/fruits" element={<Fruits />}>
              <Route path="form" element={<AddFruit />} />
              <Route path="list" element={<List />} />
            </Route>

            <Route path="*" element={<Error />} />
          </Routes>
          
        </BrowserRouter>

This setup facilitates routing within a React application, users could visit the Home page at '/' path. Users that navigate to the '/fruits' endpoint to see the Fruit layout component, this component contains and Outlet. They can then navigate to '/fruits/form' which will render the AddFruit component rendered within the Fruits layout component. On the other hand if users navigate to '/fruits/list' the List component will be rendered within the Fruits layout component. The Error component is shown if the users visit routes that are not matched by the code above.

If you would like to see a more complex version of BrowserRouter refer to this tutorial, you will need to create the components and load them into an application to run the code within an application.

Sample React Router Implementation

Please checkout the finished code in this repository, ensure that you're on the react_router branch if you want to test out the application on your machine you will need to install the dependencies with the command npm install after the installation you can then run the application with the command npm start.

Additional Reading:

Userflow

Once you have set up basic routing and authentication you will want to consider your user flow and if users should be to pushed to new pages when an action is complete, use the method below to achieve this.

useNavigate This hook allows us to move our users around our application using React Router, after a user has logged in maybe you want to send them to their profile page. On the other-hand if the user is not logged in but trying to access a restricted page you could send them to a login page. Checkout this file and repo to see how you can implement this hook.

import { useNavigate } from "react-router-dom";

// Inside a functional component, wrapped inside a BrowserRouter
const navigate = useNavigate();

// Within a function
navigate("/fruits/form");

Private Routing

When you have achieved authentication within your applications you may desire to create private routes. Private routes are routes whose components are wrapped in authenticating logic. To implement this within your application you can review this file and this repo. Also checkout the code implementation below.


function RequireAuth({ children, redirectTo, user }) {
  console.log(user);
  const isAuthenticated = // Some authentication logic, ie checking email and UID
  return isAuthenticated ? children : <Navigate to={redirectTo} />;
}

// Within a React functional component, wrapped inside a BrowserRouter

   <Route
      path="form"
      element={
        <RequireAuth redirectTo="/login" user={user}>
          <AddFruit />
        </RequireAuth>
        }
    />

The RequireAuth function checks to see if the user is authenticated and then will proceed to render the appropriate component. In the case above, depending on the users authentication status the user will be directed to the AddFruit component or be redirected to the Login component.

Last updated