Page navigation with react-router-dom



This content originally appeared on DEV Community and was authored by Khang Nguyen

To navigate to pages in a React project, we use react-router-dom, which offers many features such as routing and creating layouts with , etc. Today, I’d like to show you how to use react-router-dom in a React project with Vite.

I recommend you read my article on setting up a React project here before getting started.

Installation

npm install react-router-dom

Preparation

First, we need to imagine the project we’re going to build. This project will list Pokémon data, as shown in the image below. It has several pages:

  • /home: Landing page
  • /pokemons: Pokémon list
  • /pokemons/:id Pokémon detail
  • /favorites: All your favorite Pokémon

/pokemons page

Below is the project structure

src/
├── apis/
   ├── index.ts
   └── pokemons.ts
├── assets/
   └── logo.svg
├── components/
   ├── index.ts
   └── navbar.tsx
├── pages/
   ├── favorites/
      └── page.tsx
   ├── home/
      ├── components/
      └── page.tsx
   ├── not-found/
      └── page.tsx
   ├── pokemon/
      └── page.tsx
   └── pokemons/
       ├── components/
       ├── index.ts
       └── layout.tsx
├── types/
   ├── index.ts
   ├── pokemon.ts
├── app.tsx
├── index.css
├── main.tsx
└── vite-env.d.ts
.env

Configuring Routing

To enable client-side routing in this React application, we need to wrap entire application in <BrowserRouter> component. For each page, we need to create a <Route/> component, example for path /favorites, we get this

<Route path="/favorites" element={<FavoritesPage />} />

As you can see, we have a navbar component that we want to keep at the top of these pages. So I created a layout named MainLayout which includes an <Outlet/> component to help us switch page content while keeping the navbar fixed.

import { Outlet } from "react-router-dom";
import { Navbar } from "../components";

export default function MainLayout() {
  return (
    <div>
      <Navbar />
      <Outlet />
    </div>
  );
}

Then we need to make all the pages have the same layout (with the navbar on top) and only change the content nested inside the MainLayout route. From now on, each time you access to the path /pokemons or /favorites, the client will just change the content inside the layout and keep the navbar component.

export default function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<MainLayout />}>
          <Route path="/" element={<HomePage />} />
          <Route path="/favorites" element={<FavoritesPage />} />
          <Route path="/pokemons" element={<PokemonsPage />} />
          <Route path="/pokemons/:id" element={<PokemonPage />} />
        </Route>
        <Route path="*" element={<NotFound />} />
      </Routes>
    </BrowserRouter>
  );
}

Get params

When working with react-router-dom, you might have trouble getting params of the path. For example /pokemons/:id, you need to get the id value to fetch data of a Pokemon by its id in PokemonPage.

You can use useParams hook to get it like this

const { id } = useParams();

The hook returns an object that contains all params that appear in the URL. Now you can take the id to get the Pokemon data.

That’s it for the article, I hope it can help you to set up a project with react-router-dom. If you have any comments or suggestions, please let me know, I’d love to hear them. Thanks for reading


This content originally appeared on DEV Community and was authored by Khang Nguyen