React Router: Navigating Between Pages in Single-Page Applications
Tags: reactrouter, webdev, react, javascript
Published: 2024-03-09 10:25:10

A Single-Page Application (SPA), is a web application that operates within a single HTML page. It dynamically updates its content without requiring a full page reload. This is  achieved  by loading the initial HTML, CSS, and JavaScript resources and then dynamically fetching data and updating the DOM as users interact with the application. By loading and updating only the necessary data, it provides a fluid and more responsive user experience.

`React Router` is a JavaScript library used in React applications to handle routing and navigation. It provides a declarative way to define the routes of an application and render different components based on the current URL. 

React Router allows developers to create a seamless, client-side navigation experience within a Single-Page Application by mapping URLs to specific components and managing the history and URL changes.

First thing to do is create a Browser Router and configure our first route. This will enable client side routing for our web app.

[createBrowserRouter](https://reactrouter.com/en/main/routers/create-browser-router)  is the recommended router for all React Router web projects. It uses the [DOM History API](https://developer.mozilla.org/en-US/docs/Web/API/History) to update the URL and manage the history stack. It also enables the v6.4 data APIs like `loaders`, `actions`, `fetchers` and more.

##Basic Router
To start, create and render the browser router in the entry point file of your Application, App.js in our case. We import `createBrowserRouter` and `RouterProvider`  from `react-router-dom`, and set it equal to a variable, in our case router.

```js
Const router = createBrowserRouter([

])

```

In the `createBrowserRouter` we pass in an array of route 
 objects. 

In the code example below we have a router with two pages. The home page that displays the home page element, and an about page that displays the about page element. This allows you to navigate between the home page and the about page.

App.jsx

```js

import { createBrowserRouter, RouterProvider } from 'react-router-dom';

const router = createBrowserRouter([
  {
    path: '/',
    element: <h2>home page</>,
  },
  {
    path: '/about',
    element: (
      <div>
        <h2>about page</h2>
      </div>
    ),
  },
]);


const App = () => {
  return <RouterProvider router = {router} />;
};
export default App;
```

To render the router in our Application, we return the RouterProvider component. The component has a router prop where we pass in our router variable.

##Nested Routes

The first route is often called the `root route` because the rest of the routes will render inside of it. It serves as the root layout of the user interface.

In the code example below we want the `<Landing>`, `<Newsletter>` and `<About>`  components to render inside the `<HomeLayout>` which is set as the root route's component. We achieve this by making the routes, children of the root route.

We also need to set up which page will be the index page. This is the page that will be displayed when you move to the home page, and is going to match the root route URL.

In the code example below the `<Landing>` component is set as the `index page`.

App.jsx

```js

import { createBrowserRouter, RouterProvider } from 'react-router-dom';

const router = createBrowserRouter([
  {
    path: '/',
    element: <HomeLayout />,
    children: [
      {
        index: true,
        element: <Landing />,
      },
      {
        path: 'newsletter',
        element: <Newsletter />,
      },
      {
        path: 'about',
        element: <About />,
      },
    ],
  },
]);

const App = () => {
  return <RouterProvider router = {router} />;
};
export default App;

```
We then need to tell the root route where to render its child routes. Inside the root component, we import and render `<Outlet>`

The layout on the root component is then shared across all the children nested inside it. If we have a navbar component as illustrated below, all the nested children will share this navbar component.

HomeLayout.jsx


```js
import { Outlet } from 'react-router-dom';
import Navbar from '../components/Navbar';
const HomeLayout = () => {
  return (
    <>
      <Navbar />
      <section>
        <Outlet />
      </section>
    </>
  );
};
export default HomeLayout;
```

It is recommended that all web projects use `createBrowserRouter` as it uses the full URL instead of the hash urls common in web apps before [history.pushState](https://developer.mozilla.org/en-US/docs/Web/API/History/pushState) was standardized. Full URLs are better for SEO, better for server rendering, and are just more compatible with the rest of the web platform.

While your app may only use a single router, several routers are available depending on the environment your app is running in. [Picking a Router](https://reactrouter.com/en/main/routers/picking-a-router) should help you figure out which one to use.

Thank you for following along with me in this learning process. Follow me and leave comments, added observations or questions below.