Skip to content

React Router

React Router lets you change pages inside a React app without reloading the whole page. This means the URL in the browser can change, and React will just show a different component on the screen, without refreshing the page.

graph LR A["URL changes"] --> B["Router matches path"] B --> C["Component tree updates"] C --> D["No full page reload"]

Without Router

When the URL changes, the browser usually reloads the whole page and asks the server for everything again.

With React Router

When the URL changes, only the needed part of the React app updates. No full reload.

First, install the package:

Terminal window
npm install react-router-dom

Now wrap your app with the Router:

import { BrowserRouter } from "react-router-dom";
function App() {
return (
<BrowserRouter>
<Main />
</BrowserRouter>
);
}
import { Routes, Route } from "react-router-dom";
function Main() {
return (
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
{/* Nested Route / Child Routes */}
<Route path="/user" element={<UserLayout />}>
<Route path="profile" element={<Profile />} />
<Route path="settings" element={<Settings />} />
</Route>
</Routes>
);
}
FeatureJSX RoutesObject Routes
Easy to readEasyA bit harder
Works well for big appsOkayBetter
Setting routes with dataHardEasy
Used in large appsLessMore

Link is used to move between pages without reloading the page.

import { Link } from "react-router-dom";
<Link to="/about">Go to About</Link>;

NavLink works just like Link, but it also tells you if that link is the one currently active (the page you are on right now).

import { NavLink } from "react-router-dom";
<NavLink to="/about">About</NavLink>;
FeatureLinkNavLink
Moves between pagesYesYes
Shows which page is activeNoYes
Best used forSimple linksNavbars and menus
<NavLink to="/about" className={({ isActive }) => (isActive ? "active" : "")]}>
About
</NavLink>
.active {
color: red;
font-weight: bold;
}
graph LR A["Current URL"] --> B{"Matches NavLink path?"} B -- "Yes" --> C["isActive = true"] B -- "No" --> D["isActive = false"]

Dynamic routes are useful when you want to show pages like user profiles or product pages, where the page content changes based on an ID or name in the URL.

/users/1
/users/2
/users/3

This is how you set up a dynamic route:

<Route path="/user/:id" element={<User />} />

Here, :id simply means:

:id = a value that can change

You can grab that value like this:

import { useParams } from "react-router-dom";
function User() {
const { id } = useParams();
return <h1>User ID: {id}</h1>;
}
graph TD A["URL: /user/10"] --> B["useParams()"] B --> C["{ id: '10' }"]

Route:

<Route path="/user/:id" element={<User />} />

Component:

import { useParams } from "react-router-dom";
import { useEffect, useState } from "react";
function User() {
const { id } = useParams();
const [user, setUser] = useState(null);
useEffect(() => {
fetch(`https://api.example.com/users/${id}`)
.then((res) => res.json())
.then((data) => setUser(data));
}, [id]);
if (!user) return <p>Loading...</p>;
return (
<div>
<h1>{user.name}</h1>
<p>{user.email}</p>
</div>
);
}
<Route path="/user" element={<UserLayout />}>
<Route path="profile" element={<Profile />} />
<Route path="settings" element={<Settings />} />
</Route>

Use useNavigate when you want to send the user to a different page from your code, instead of them clicking a link (for example, after they submit a form).

import { useNavigate } from "react-router-dom";
const navigate = useNavigate();
navigate("/about");

React Router has a built-in way of checking which route matches the current URL.

/user/:id matches:
/user/1
/user/abc
graph TD A["User clicks Link"] --> B["URL changes"] B --> C["Router matches route"] C --> D["Component renders"] D --> E["useParams extracts values"] E --> F["API fetch if needed"] F --> G["UI updates"]
useEffect(() => {
fetchData();
}, []); // Wrong when id is used inside

Correct way:

useEffect(() => {
fetchData(id);
}, [id]);
  • You can think of the URL itself as a kind of state in your app.
  • The components shown on screen change depending on what the URL is.
  • Dynamic routing makes it possible to build things like profile pages, product pages, and dashboards.
graph TD APP["/app"] --> HOME["Home"] APP --> USERS["Users"] USERS --> DETAIL["UserDetail (/user/:id)"]