16_React Routing - Maniconserve/React-Wiki GitHub Wiki

What is Routing?

In a traditional website, clicking a link loads a completely new HTML page from the server. In React, everything is a Single Page Application (SPA) — there is only one HTML file (index.html). Routing in React means swapping components in and out based on the URL, without reloading the page.

React does not have built-in routing. The most widely used library is React Router.


Installation

npm install react-router-dom

Core Concepts

Concept What it does
BrowserRouter Wraps the entire app — enables routing
Routes Container that holds all your routes
Route Maps a URL path to a component
Link Navigates between pages without reloading
NavLink Like Link but adds an active class when the route matches
useNavigate Programmatically navigate to a route in code
useParams Read dynamic values from the URL
useLocation Read the current URL path, search params and state

Basic Setup

Wrap your entire app in BrowserRouter — usually in index.js.

// index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import App from './App';
 
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>
);

Defining Routes

// App.js
import { Routes, Route } from 'react-router-dom';
import Home from './pages/Home';
import About from './pages/About';
import Contact from './pages/Contact';
import NotFound from './pages/NotFound';
 
function App() {
  return (
    <Routes>
      <Route path="/"        element={<Home />} />
      <Route path="/about"   element={<About />} />
      <Route path="/contact" element={<Contact />} />
      <Route path="*"        element={<NotFound />} /> {/* catches unknown routes */}
    </Routes>
  );
}
 
export default App;
  • path="/" — matches the home URL
  • path="*" — matches anything that didn't match above — use for a 404 page

Navigating with Link

Never use a plain <a href=""> tag in React Router — it causes a full page reload. Use <Link> instead.

import { Link } from 'react-router-dom';
 
function Navbar() {
  return (
    <nav>
      <Link to="/">Home</Link>
      <Link to="/about">About</Link>
      <Link to="/contact">Contact</Link>
    </nav>
  );
}

<Link to="/about"> updates the URL and swaps the component — no page reload.


NavLink — Highlight the Active Link

NavLink works like Link but automatically adds an active class when the route matches. Useful for navigation menus.

import { NavLink } from 'react-router-dom';
 
function Navbar() {
  return (
    <nav>
      <NavLink to="/"       className={({ isActive }) => isActive ? 'active' : ''}>Home</NavLink>
      <NavLink to="/about"  className={({ isActive }) => isActive ? 'active' : ''}>About</NavLink>
      <NavLink to="/contact"className={({ isActive }) => isActive ? 'active' : ''}>Contact</NavLink>
    </nav>
  );
}
/* App.css */
.active {
  font-weight: bold;
  color: blue;
  border-bottom: 2px solid blue;
}

Dynamic Routes with URL Parameters

Use :paramName in the path to create a dynamic segment. The value in the URL becomes a variable you can read with useParams.

// App.js
<Route path="/user/:id" element={<UserProfile />} />
// UserProfile.jsx
import { useParams } from 'react-router-dom';
 
function UserProfile() {
  const { id } = useParams(); // reads the :id from the URL
 
  return <h1>Viewing profile of user {id}</h1>;
}

Visiting /user/42 renders: Viewing profile of user 42
Visiting /user/arjun renders: Viewing profile of user arjun


Programmatic Navigation with useNavigate

Sometimes you need to navigate in code — after a form submission, after login, after a button click. Use useNavigate for this.

import { useNavigate } from 'react-router-dom';
 
function LoginForm() {
  const navigate = useNavigate();
 
  function handleSubmit(e) {
    e.preventDefault();
    // do login logic...
    navigate('/dashboard'); // redirect after login
  }
 
  return (
    <form onSubmit={handleSubmit}>
      <input type="text" placeholder="Username" />
      <button type="submit">Login</button>
    </form>
  );
}
// Navigate back to previous page
navigate(-1);
 
// Navigate forward
navigate(1);

useLocation — Read the Current URL

useLocation returns an object with information about the current URL. It updates every time the URL changes.

import { useLocation } from 'react-router-dom';
 
function App() {
  const location = useLocation();
 
  console.log(location);
  // {
  //   pathname: '/about',       — the current path
  //   search:   '?tab=profile', — query string
  //   hash:     '#section1',    — hash fragment
  //   state:    { from: '/' }   — state passed via navigate()
  //   key:      'default'
  // }
}

A. Show active page name

import { useLocation } from 'react-router-dom';
 
function Navbar() {
  const location = useLocation();
 
  return (
    <nav>
      <p>Current page: {location.pathname}</p>
    </nav>
  );
}
// On /about → "Current page: /about"
// On /       → "Current page: /"

B. Reading Query String (?search=react)

Query strings are the ?key=value part of a URL. Use useLocation to get them and the built-in URLSearchParams to read them.

import { useLocation } from 'react-router-dom';
 
function SearchResults() {
  const location = useLocation();
  const params = new URLSearchParams(location.search);
  const query = params.get('q'); // reads ?q=react
 
  return <h1>Results for: {query}</h1>;
}
// URL: /search?q=react  →  "Results for: react"
// URL: /search?q=hooks  →  "Results for: hooks"

C. Passing State Between Routes

You can pass data silently through navigation using state. It does not appear in the URL.

// From page — pass state via navigate
import { useNavigate } from 'react-router-dom';
 
function Home() {
  const navigate = useNavigate();
 
  return (
    <button onClick={() => navigate('/profile', { state: { from: 'Home', userId: 5 } })}>
      Go to Profile
    </button>
  );
}
// To page — read state via useLocation
import { useLocation } from 'react-router-dom';
 
function Profile() {
  const location = useLocation();
  const { from, userId } = location.state || {};
 
  return <p>Came from: {from} — User ID: {userId}</p>;
  // "Came from: Home — User ID: 5"
}

Nested Routes

You can nest routes inside each other. The parent renders a layout (like a sidebar or header) and the child routes render inside it using <Outlet />.

// App.js
import { Routes, Route } from 'react-router-dom';
import Dashboard from './pages/Dashboard';
import Overview from './pages/Overview';
import Settings from './pages/Settings';
 
function App() {
  return (
    <Routes>
      <Route path="/dashboard" element={<Dashboard />}>
        <Route path="overview"  element={<Overview />} />
        <Route path="settings"  element={<Settings />} />
      </Route>
    </Routes>
  );
}
// Dashboard.jsx — parent layout
import { Outlet, Link } from 'react-router-dom';
 
function Dashboard() {
  return (
    <div>
      <h1>Dashboard</h1>
      <nav>
        <Link to="overview">Overview</Link>
        <Link to="settings">Settings</Link>
      </nav>
 
      <Outlet /> {/* child route renders here */}
    </div>
  );
}
  • /dashboard/overview → renders Dashboard with Overview inside <Outlet />
  • /dashboard/settings → renders Dashboard with Settings inside <Outlet />

Folder Structure for Pages

It is a common convention to keep page-level components in a pages/ folder.

src/
  pages/
    Home.jsx
    About.jsx
    Contact.jsx
    NotFound.jsx
    Dashboard.jsx
  components/
    Navbar.jsx
    Footer.jsx
  App.js
  index.js

Full Working Example

// index.js
import { BrowserRouter } from 'react-router-dom';
import App from './App';
 
root.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>
);
 
 
// App.js
import { Routes, Route } from 'react-router-dom';
import Navbar from './components/Navbar';
import Home from './pages/Home';
import About from './pages/About';
import UserProfile from './pages/UserProfile';
import NotFound from './pages/NotFound';
 
function App() {
  return (
    <div>
      <Navbar />
      <Routes>
        <Route path="/"          element={<Home />} />
        <Route path="/about"     element={<About />} />
        <Route path="/user/:id"  element={<UserProfile />} />
        <Route path="*"          element={<NotFound />} />
      </Routes>
    </div>
  );
}
 
 
// components/Navbar.jsx
import { NavLink } from 'react-router-dom';
 
function Navbar() {
  return (
    <nav>
      <NavLink to="/"      className={({ isActive }) => isActive ? 'active' : ''}>Home</NavLink>
      <NavLink to="/about" className={({ isActive }) => isActive ? 'active' : ''}>About</NavLink>
    </nav>
  );
}
 
 
// pages/UserProfile.jsx
import { useParams } from 'react-router-dom';
 
function UserProfile() {
  const { id } = useParams();
  return <h1>User Profile — ID: {id}</h1>;
}

Quick Reference

Goal Code
Install npm install react-router-dom
Wrap app <BrowserRouter> in index.js
Define routes <Routes><Route path="/" element={<Home />} /></Routes>
Navigate via link <Link to="/about">About</Link>
Active link styling <NavLink to="/about" className={({ isActive }) => isActive ? 'active' : ''}>
Dynamic route <Route path="/user/:id" element={<UserProfile />} />
Read URL param const { id } = useParams()
Navigate in code const navigate = useNavigate(); navigate('/path')
404 page <Route path="*" element={<NotFound />} />
Nested route outlet <Outlet /> inside parent component
Read current URL const location = useLocation(); location.pathname
Read query string new URLSearchParams(location.search).get('key')
Pass state via navigate navigate('/path', { state: { key: val } })
Read passed state const location = useLocation(); location.state
⚠️ **GitHub.com Fallback** ⚠️