Skip
Arish's avatar

20. React Router Basics


React Router

React Router is the standard routing library for React, enabling navigation between views in a single-page application.

Installation

bash
1npm install react-router-dom

Basic Setup

jsx
1import { BrowserRouter, Routes, Route } from 'react-router-dom'
2
3function App() {
4  return (
5    <BrowserRouter>
6      <Routes>
7        <Route path="/" element={<Home />} />
8        <Route path="/about" element={<About />} />
9        <Route path="/contact" element={<Contact />} />
10      </Routes>
11    </BrowserRouter>
12  )
13}
jsx
1import { Link } from 'react-router-dom'
2
3function Navigation() {
4  return (
5    <nav>
6      <Link to="/">Home</Link>
7      <Link to="/about">About</Link>
8      <Link to="/contact">Contact</Link>
9    </nav>
10  )
11}
jsx
1import { NavLink } from 'react-router-dom'
2
3function Navigation() {
4  return (
5    <nav>
6      <NavLink 
7        to="/"
8        className={({ isActive }) => isActive ? 'active' : ''}
9      >
10        Home
11      </NavLink>
12      
13      <NavLink
14        to="/about"
15        style={({ isActive }) => ({
16          fontWeight: isActive ? 'bold' : 'normal'
17        })}
18      >
19        About
20      </NavLink>
21    </nav>
22  )
23}

Programmatic Navigation

jsx
1import { useNavigate } from 'react-router-dom'
2
3function LoginForm() {
4  const navigate = useNavigate()
5  
6  const handleSubmit = async (e) => {
7    e.preventDefault()
8    await login()
9    navigate('/dashboard')  // Navigate after login
10  }
11  
12  const goBack = () => navigate(-1)  // Go back
13  const goForward = () => navigate(1)  // Go forward
14  
15  return (
16    <form onSubmit={handleSubmit}>
17      {/* form fields */}
18      <button type="submit">Login</button>
19      <button type="button" onClick={goBack}>Cancel</button>
20    </form>
21  )
22}

Route Parameters

jsx
1// Routes
2<Routes>
3  <Route path="/users/:userId" element={<UserProfile />} />
4  <Route path="/posts/:postId/comments/:commentId" element={<Comment />} />
5</Routes>
6
7// Component
8import { useParams } from 'react-router-dom'
9
10function UserProfile() {
11  const { userId } = useParams()
12  
13  return <h1>User ID: {userId}</h1>
14}
15
16function Comment() {
17  const { postId, commentId } = useParams()
18  
19  return (
20    <div>
21      <p>Post: {postId}</p>
22      <p>Comment: {commentId}</p>
23    </div>
24  )
25}

Query Parameters

jsx
1import { useSearchParams } from 'react-router-dom'
2
3function ProductList() {
4  const [searchParams, setSearchParams] = useSearchParams()
5  
6  const category = searchParams.get('category')
7  const sort = searchParams.get('sort') || 'name'
8  
9  const setCategory = (cat) => {
10    setSearchParams({ category: cat, sort })
11  }
12  
13  return (
14    <div>
15      <p>Category: {category}</p>
16      <p>Sort: {sort}</p>
17      <button onClick={() => setCategory('electronics')}>
18        Electronics
19      </button>
20    </div>
21  )
22}
23
24// URL: /products?category=electronics&sort=price

Nested Routes

jsx
1function App() {
2  return (
3    <Routes>
4      <Route path="/" element={<Layout />}>
5        <Route index element={<Home />} />
6        <Route path="about" element={<About />} />
7        <Route path="dashboard" element={<Dashboard />}>
8          <Route index element={<DashboardHome />} />
9          <Route path="settings" element={<Settings />} />
10          <Route path="profile" element={<Profile />} />
11        </Route>
12      </Route>
13    </Routes>
14  )
15}
16
17// Layout component with Outlet
18import { Outlet } from 'react-router-dom'
19
20function Layout() {
21  return (
22    <div>
23      <Header />
24      <main>
25        <Outlet />  {/* Child routes render here */}
26      </main>
27      <Footer />
28    </div>
29  )
30}
31
32function Dashboard() {
33  return (
34    <div>
35      <DashboardNav />
36      <Outlet />  {/* Nested dashboard routes */}
37    </div>
38  )
39}

404 Not Found

jsx
1<Routes>
2  <Route path="/" element={<Home />} />
3  <Route path="/about" element={<About />} />
4  <Route path="*" element={<NotFound />} />  {/* Catch all */}
5</Routes>
6
7function NotFound() {
8  return (
9    <div>
10      <h1>404 - Page Not Found</h1>
11      <Link to="/">Go Home</Link>
12    </div>
13  )
14}

useLocation Hook

jsx
1import { useLocation } from 'react-router-dom'
2
3function CurrentPath() {
4  const location = useLocation()
5  
6  return (
7    <div>
8      <p>Path: {location.pathname}</p>
9      <p>Search: {location.search}</p>
10      <p>Hash: {location.hash}</p>
11      <p>State: {JSON.stringify(location.state)}</p>
12    </div>
13  )
14}
15
16// Passing state through navigation
17<Link to="/checkout" state={{ from: 'cart' }}>Checkout</Link>
18
19navigate('/checkout', { state: { from: 'cart' } })

Route Configuration Object

jsx
1import { useRoutes } from 'react-router-dom'
2
3const routes = [
4  {
5    path: '/',
6    element: <Layout />,
7    children: [
8      { index: true, element: <Home /> },
9      { path: 'about', element: <About /> },
10      {
11        path: 'dashboard',
12        element: <Dashboard />,
13        children: [
14          { index: true, element: <DashboardHome /> },
15          { path: 'settings', element: <Settings /> }
16        ]
17      },
18      { path: '*', element: <NotFound /> }
19    ]
20  }
21]
22
23function App() {
24  const element = useRoutes(routes)
25  return element
26}

Redirects

jsx
1import { Navigate } from 'react-router-dom'
2
3// In routes
4<Route path="/old-path" element={<Navigate to="/new-path" replace />} />
5
6// In component
7function ProtectedRoute({ children }) {
8  const { user } = useAuth()
9  
10  if (!user) {
11    return <Navigate to="/login" replace />
12  }
13  
14  return children
15}

React Router makes building multi-page React apps straightforward!