DEV Community

Cover image for Page navigation with react-router-dom
Khang Nguyen
Khang Nguyen

Posted on

Page navigation with react-router-dom

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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 />} />
Enter fullscreen mode Exit fullscreen mode

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>
  );
}
Enter fullscreen mode Exit fullscreen mode

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>
  );
}
Enter fullscreen mode Exit fullscreen mode

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();
Enter fullscreen mode Exit fullscreen mode

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

Top comments (0)