DEV Community

Abhay Singh Kathayat
Abhay Singh Kathayat

Posted on

Understanding React Router Basics: Managing Navigation in React

React Router Basics

React Router is a powerful library used for routing in React applications. It allows developers to define routes in their application and manage navigation between different views or components. React Router makes it easy to create single-page applications (SPAs) by handling dynamic routing and URL-based navigation.


Key Concepts of React Router

  1. Routing: It refers to the process of navigating from one URL to another within your application.
  2. SPA (Single Page Application): React Router is designed for SPAs, where the application is loaded once, and only parts of the page are updated when the user navigates to different routes.

Core Components of React Router

  1. BrowserRouter (or HashRouter):
    • This component is the wrapper that holds your routing logic and is used to enable navigation.
    • BrowserRouter uses the HTML5 history API to manipulate the browser’s URL and keeps the UI in sync.
    • For older browsers or in cases where HTML5 history API is not supported, HashRouter can be used (though it uses hash-based routing).

Example:

   import { BrowserRouter } from 'react-router-dom';

   const App = () => {
     return (
       <BrowserRouter>
         <Routes />
       </BrowserRouter>
     );
   };
Enter fullscreen mode Exit fullscreen mode
  1. Routes:
    • The <Routes> component is used to define all the routes in your application. It acts as a container for individual Route elements.
    • In React Router v6, Routes replaces the previous Switch component.

Example:

   import { Routes, Route } from 'react-router-dom';

   const Routes = () => {
     return (
       <Routes>
         <Route path="/" element={<Home />} />
         <Route path="/about" element={<About />} />
       </Routes>
     );
   };
Enter fullscreen mode Exit fullscreen mode
  1. Route:
    • The <Route> component defines a mapping between a URL path and a component.
    • The path prop defines the URL, and the element prop specifies the component that should render when the route is matched.

Example:

   <Route path="/" element={<Home />} />
Enter fullscreen mode Exit fullscreen mode
  1. Link:
    • The <Link> component is used to navigate between different routes without reloading the page. It renders an anchor (<a>) tag that reacts to click events and updates the browser's URL accordingly.

Example:

   import { Link } from 'react-router-dom';

   const Navigation = () => {
     return (
       <nav>
         <Link to="/">Home</Link>
         <Link to="/about">About</Link>
       </nav>
     );
   };
Enter fullscreen mode Exit fullscreen mode
  1. useNavigate:
    • The useNavigate hook is used to programmatically navigate to different routes.
    • This hook is typically used inside event handlers or side effects.

Example:

   import { useNavigate } from 'react-router-dom';

   const Login = () => {
     const navigate = useNavigate();

     const handleLogin = () => {
       // Perform login logic
       navigate('/dashboard');
     };

     return (
       <button onClick={handleLogin}>Login</button>
     );
   };
Enter fullscreen mode Exit fullscreen mode

Basic Routing Example

Here’s a basic example that demonstrates React Router in a functional React app:

import React from 'react';
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';

const Home = () => <h2>Home Page</h2>;
const About = () => <h2>About Page</h2>;
const Contact = () => <h2>Contact Page</h2>;

const App = () => {
  return (
    <BrowserRouter>
      <div>
        <nav>
          <ul>
            <li>
              <Link to="/">Home</Link>
            </li>
            <li>
              <Link to="/about">About</Link>
            </li>
            <li>
              <Link to="/contact">Contact</Link>
            </li>
          </ul>
        </nav>

        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/about" element={<About />} />
          <Route path="/contact" element={<Contact />} />
        </Routes>
      </div>
    </BrowserRouter>
  );
};

export default App;
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • The BrowserRouter component wraps the entire app to enable routing.
  • The Link component is used to create navigation links that don’t trigger page reloads.
  • The Routes component contains all the routes, and each Route element maps a URL path to a component (e.g., Home, About, or Contact).
  • Clicking the Link will update the URL and render the corresponding component.

Nested Routing

React Router also supports nested routes, allowing you to define routes within other routes.

import React from 'react';
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom';

const Home = () => <h2>Home Page</h2>;

const Dashboard = () => (
  <div>
    <h2>Dashboard</h2>
    <nav>
      <Link to="profile">Profile</Link>
      <Link to="settings">Settings</Link>
    </nav>

    <Routes>
      <Route path="profile" element={<h3>Profile Page</h3>} />
      <Route path="settings" element={<h3>Settings Page</h3>} />
    </Routes>
  </div>
);

const App = () => {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="dashboard/*" element={<Dashboard />} />
      </Routes>
    </BrowserRouter>
  );
};

export default App;
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • The /dashboard route has nested routes: /dashboard/profile and /dashboard/settings.
  • By using the * wildcard in the parent route (path="dashboard/*"), React Router knows to render the child routes inside the Dashboard component.

Redirecting with Navigate

You can programmatically navigate users to different routes using the Navigate component or the useNavigate hook.

import { Navigate } from 'react-router-dom';

// Redirect to a different route
const Redirect = () => <Navigate to="/about" />;
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • The Navigate component will automatically redirect the user to the /about route when rendered.

Route Parameters

You can define dynamic routes by including route parameters, which can be used to pass values in the URL.

import React from 'react';
import { BrowserRouter, Routes, Route, useParams } from 'react-router-dom';

const UserProfile = () => {
  const { userId } = useParams();
  return <h2>User Profile for user: {userId}</h2>;
};

const App = () => {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/user/:userId" element={<UserProfile />} />
      </Routes>
    </BrowserRouter>
  );
};

export default App;
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • The :userId in the route path is a route parameter.
  • The useParams hook is used inside the UserProfile component to extract the value of userId from the URL and render it on the page.

Conclusion

React Router makes navigating between views in a React application easy and efficient. With its components like BrowserRouter, Route, Link, and hooks like useNavigate, you can create dynamic, single-page applications with complex routing logic. By understanding the basics of React Router, including handling routes, nested routes, and route parameters, you can easily manage navigation in your React apps.


Top comments (6)

Collapse
 
codewander profile image
Anon

For those that are looking for minimal routing library that doesn't push breaking new major versions regularly, there is also wouter.

Collapse
 
abhay_yt_52a8e72b213be229 profile image
Abhay Singh Kathayat

Thanks for the suggestion, Kanishka! Wouter sounds like a great option for projects where simplicity and stability are key. I'll definitely check it out. Have you used it in any of your projects? Would love to hear about your experience with it

Collapse
 
codewander profile image
Anon

I haven't used it yet. I have studied the docs and I am looking for an excuse to use it. I did burn some time using remix, while they announced remix was being renamed, and then I read the extensive threads talking about the frustration with React Router churning through breaking changes for many years now, and realized my experience with remix changing quickly was nothing new.

Thread Thread
 
abhay_yt_52a8e72b213be229 profile image
Abhay Singh Kathayat

I totally get your frustration, Kanishka. It’s tough when tools you invest time in keep changing, especially with things like Remix’s renaming or React Router's breaking changes. I’ve also read about the churn with React Router, and it can be draining to deal with frequent breaking changes in a production project. That’s one of the reasons I’m considering Wouter too. It seems like a more stable choice with a minimal API, and the fact that it doesn’t frequently introduce breaking changes could be a big win for long-term projects. Have you come across any other alternatives that offer similar stability, or do you feel like Wouter is the best option in that regard?

Thread Thread
 
codewander profile image
Anon

I haven't done an exhaustive NPM search for projects with similar goals as Wouter yet, but I will report back if/when I do that.

Thread Thread
 
abhay_yt_52a8e72b213be229 profile image
Abhay Singh Kathayat

Thanks for the insight, Kanishka! I haven’t done an exhaustive NPM search for projects with similar goals as Wouter yet either, but I’ll definitely look into it and report back if I come across any interesting alternatives. Let me know if you find something worth checking out as well! Also, can we connect through Twitter? It would be great to keep in touch and share insights!