16_React Routing - Maniconserve/React-Wiki GitHub Wiki
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.
npm install react-router-dom| 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 |
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>
);// 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
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 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;
}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
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 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'
// }
}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: /"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"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"
}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→ rendersDashboardwithOverviewinside<Outlet /> -
/dashboard/settings→ rendersDashboardwithSettingsinside<Outlet />
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
// 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>;
}| 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 |