Dynamic Navigation with React Router

Hero image for Dynamic Navigation with React Router. Image by Jared Murray.
Hero image for 'Dynamic Navigation with React Router.' Image by Jared Murray.

Navigation is at the very core of any web application. Users expect smooth transitions between pages, and React Router makes this easy to achieve without fullpage reloads. Whether we are building a simple website or a complex singlepage application, React Router provides the tools we need to handle navigation dynamically.

In this article, I will explore how React Router works, how to set up dynamic routes, and best practices for managing navigation effectively.


Setting up React Router

To get started with React Router, we need to install the package:

yarn add react-router-dom

Once installed, we can wrap our application with BrowserRouter to enable routing:

import { BrowserRouter, Routes, Route } from "react-router-dom";import HomePage from "./HomePage";import AboutPage from "./AboutPage";const App = () => (  <BrowserRouter>    <Routes>      <Route path="/" element={<HomePage />} />      <Route path="/about" element={<AboutPage />} />    </Routes>  </BrowserRouter>);export default App;

This setup defines two routes: the home page (/) and the about page (/about). React Router renders the appropriate component based on the URL.

Now that our routes are in place, we need a way for users to navigate between them efficiently. This is where React Router's <Link> component comes in.


Instead of using traditional anchor (<a>) tags, React Router provides the <Link> component to enable clientside navigation, which can be used like this:

import { Link } from "react-router-dom";const Navigation = () => (  <nav>    <Link to="/">Home</Link>    <Link to="/about">About</Link>  </nav>);export default Navigation;

By using the <Link> component, we can ensure that navigation is handled efficiently, preventing fullpage reloads and improving the user experience.


Using Dynamic Route Parameters

Many applications need flexible URLs. For example, a user profile page might need to display details based on the username in the URL. React Router makes this easy with dynamic route parameters.

We can access route parameters using useParams, like this:

import { useParams } from "react-router-dom";const Profile = () => {  const { username } = useParams();  return <h1>Profile of {username}</h1>;};

.. and to define a route that accepts a parameter:

<Routes>  <Route path="/profile/:username" element={<Profile />} /></Routes>

Now, navigating to /profile/ellie will display Profile of ellie, with username dynamically retrieved from the URL.


Handling Programmatic Navigation

Sometimes, we need to navigate users dynamically, such as after form submission or authentication. React Router provides the useNavigate hook for this, which we can use like this:

import { useNavigate } from "react-router-dom";const Login = () => {  const navigate = useNavigate();  const handleLogin = () => {    // Perform login logic    navigate("/dashboard");  };  return <button onClick={handleLogin}>Log In</button>;};

Calling navigate("/dashboard") will update the URL programmatically, directing users to the dashboard once they log in.


Redirecting and Protecting Routes

Some parts of an application should only be accessible under certain conditions. For example, a dashboard might require users to be logged in. We can use protected routes to handle this:

import { Navigate } from "react-router-dom";const ProtectedRoute = ({ isAuthenticated, children }: { isAuthenticated: boolean; children: JSX.Element }) => {  return isAuthenticated ? children : <Navigate to="/login" />;};// Usage in routes<Routes>  <Route path="/dashboard" element={<ProtectedRoute isAuthenticated={userLoggedIn}><Dashboard /></ProtectedRoute>} /></Routes>;

Here, if the user is not authenticated, then they are redirected to the login page instead of accessing the protected content.


Best Practices for React Router Navigation

To keep navigation smooth and maintainable, consider the following best practices:

  1. Use Semantic URLs

    – Keep URLs meaningful and predictable (/profile/:id instead of /user?id=123).
  2. Handle Fallback Routes

    – Use a wildcard route (*), so users see a custom error page instead of a blank screen.
  3. Optimise Route Loading

    – Use lazy loading (React.lazy) to improve performance by loading components only when needed.
  4. Preserve Scroll Position

    – Implement logic to restore scroll position when navigating between pages.

By following these best practices, we can ensure that our navigation is structured, efficient, and userfriendly. Perhaps just as importantly: we can make sure that search engines can easily navigate our application too...


Wrapping up

React Router provides a powerful way to handle dynamic navigation in React applications. Whether we are using route parameters, programmatic navigation, or protected routes, it ensures a seamless experience without unnecessary page reloads.

Key Takeaways

  • React Router enables singlepage navigation, preventing fullpage reloads.
  • The <Link> component provides efficient clientside navigation.
  • Dynamic routes with parameters allow flexible URL structures.
  • useNavigate enables programmatic navigation for handling redirects.
  • Protected routes help control access to restricted pages.

Understanding these core concepts allows us to build responsive and intuitive navigation experiences in React applications.


Categories:

  1. Development
  2. Front‑End Development
  3. Gatsby
  4. Guides
  5. JavaScript
  6. React