React Router DOM

React Router DOM is essential for managing routing in web applications. It re-exports the react-router package for web apps and react-router-native for native apps. This guide covers how to set up and use various components of React Router DOM.

Installation

First, install react-router-dom from npm:

npm i react-router-dom
Info

React officially supports single-page applications. For multi-page routing, use the react-router-dom library.

BrowserRouter

BrowserRouter is the main parent component that enables the use of React Router in your application. Include it in your main.jsx or index.jsx file like this:

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

<React.StrictMode>
    <BrowserRouter>
        <App />
    </BrowserRouter>
</React.StrictMode>;
Note

BrowserRouter should wrap your entire application to ensure that all routes and navigation features are available throughout the app.

Routes & Route

Routes is the parent component for all individual Route components. Define your routes as follows:

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

<Routes>
    <Route path="/" element={<Home />} component={Home} />
    <Route path="/data" component={Data} />
</Routes>;
Pitfall

The component attribute takes priority over the element attribute if both are present. Prefer using element in new projects.

Danger

When passing props via routes, use the element attribute. In v5, this was done with render, but now it has been replaced by element.

Instead of using <a> tags for navigation, React Router provides the <Link> component:

<Link to="/contact">Contact</Link>

In anchor tags, the link is passed in the href attribute, but in the Link component, the link is passed in the to prop.

Note

Using <Link> helps with client-side routing and prevents full page reloads.

The NavLink component is similar to the Link component but is specifically used for navigation bars. It provides an "active" class to the link that corresponds to the current page.

<NavLink> is similar to <Link> but provides an active class for styling the active link:

<NavLink to="/"
    style={({ isActive }) => {
            return {color: isActive ? '#153448' : 'steelblue'}
        }
    }
>Home</NavLink>
<NavLink to="/about"
    style={({ isActive }) => {
            return {color: isActive ? '#153448' : 'steelblue'}
        }
    }
>About</NavLink>

When using the NavLink component, it automatically applies an active class to the link when the corresponding page is being viewed. This is useful for indicating the current page in the navigation bar.

Info

The active class is automatically applied to the link corresponding to the current route.

Error Page

Show an error page for non-existent routes:

<Route path="/*" component={Error} />
Warning

Always include a catch-all route to handle undefined routes and improve user experience.

Nested Routing

Define nested routes for structured navigation:

<Route path="/" component={Menu}>
    <Route path="about" component={About} />
    <Route path="contact" component={Contact} />
    <Route path="service" component={Service} />
    <Route path="events" component={Events}>
        <Route path="anual" component={Anual} />
        <Route path="monthly" component={Monthly} />
    </Route>
</Route>
Pitfall

Without proper configuration, nested routes may not display correctly. Ensure the layout is managed correctly using Outlet.

Outlet & Shared Layout

To properly display page data for nested routes, we use the Outlet component. The Outlet component allows us to define a shared layout that remains consistent while only the nested content changes.

<div style={styles.container}>
    <NavLink to="/">Home</NavLink>
    <NavLink to="/about">About</NavLink>
    <NavLink to="/contact">Contact</NavLink>
    <NavLink to="/service">Service</NavLink>
</div>
<Outlet />

The Outlet component is called at the end of the menu to render the nested route's content. This setup is akin to fixed components seen on sites like Instagram, where the profile data remains static while the content (e.g., Posts, Reels, Mentions) changes.

Using Outlet helps us manage scenarios where parts of the layout (like a navbar) stay the same across different pages, while only specific sections of the page content update based on the nested route.

One common issue is that navigating to the root path (e.g., / or localhost:5173) may only display the menu. We'll address this by defining an index route to handle the default content for the root path.

Deep Dive

Outlet serves as a placeholder for nested route content within the parent component. Read article

Index Route

Ensure a default page loads for the base route.

To display the home page when navigating to / or localhost:5173, we use the index route. This ensures that the home page content is shown alongside the menu.

<Route path='/' Component={Menu}>
    <Route index Component={Home} />
    <Route path='about' Component={About} />
    <Route path='contact' Component={Contact} />
    <Route path='service' Component={Service} />
</Route>

By defining an index route within the main route, we ensure the home page is displayed at the root path. Alternatively, you can use an empty string ('') or a forward slash ('/') for the home page route:

<Route path='' Component={Home} />
<Route path='/' Component={Home} />

Both methods will display the home page content when navigating to / or localhost:5173.

Info

The index attribute specifies the default child route for the parent route.

useNavigate

The useNavigate hook allows for programmatic navigation without using Link or NavLink.

First, import useNavigate from react-router-dom:

import { useNavigate } from "react-router-dom"

To navigate to a specific route, you can define a function that uses navigate:

const navigate = useNavigate();

const about = () => {
    navigate('/about');
}

return (
    <>
        <h1>Home</h1>
        <button onClick={about}>About More</button>
    </>
);

For navigation similar to the forward and back buttons found in many websites, you can define the following functions:

const GoBack = () => {
    navigate(-1);
}

const GoForward = () => {
    navigate(+1);
}

return (
    <>
        <button onClick={GoBack}>Go Back</button>
        <button onClick={GoForward}>Go Forward</button>
    </>
);
Task

Create a Login and Register pages, When user fill the form and click on register button then user navigate to Login page and when user click on login button then it navigate to home page, use to navigate programmatically with useNavigate.

Handle navigation history with navigate:

const GoBack = () => {
    navigate(-1);
};
const GoForward = () => {
    navigate(+1);
};

<button onClick={() => GoBack()}>Go Back</button>
<button onClick={() => GoForward()}>Go Forward</button>
Info

Use negative and positive values to navigate backward and forward in the history stack, respectively.

Task

Practice Implementing React Router

Objective: Set up routing in a sample React application using React Router DOM.

  1. Install React Router DOM:

    npm install react-router-dom
    
  2. Create Basic App Structure:

    Create App.jsx, Home.jsx, About.jsx, Contact.jsx, Error.jsx, and Menu.jsx components.

    // Home.jsx
    const Home = () => <h2>Home Page</h2>;
    export default Home;
    
    // About.jsx
    const About = () => <h2>About Page</h2>;
    export default About;
    
    // Contact.jsx
    const Contact = () => <h2>Contact Page</h2>;
    export default Contact;
    
    // Error.jsx
    const Error = () => <h2>404 - Not Found</h2>;
    export default Error;
    
    // Menu.jsx
    import { Outlet, NavLink } from 'react-router-dom';
    
    const Menu = () => (
        <>
            <nav>
                <NavLink to="/">Home</NavLink>
                <NavLink to="/about">About</NavLink>
                <NavLink to="/contact">Contact</NavLink>
            </nav>
            <Outlet />
        </>
    );
    export default Menu;
    
  3. Configure Routing in App.jsx:

    import { BrowserRouter, Routes, Route } from "react-router-dom";
    import Home from "./Home";
    import About from "./About";
    import Contact from "./Contact";
    import Error from "./Error";
    import Menu from "./Menu";
    
    const App = () => (
        <BrowserRouter>
            <Routes>
                <Route path="/" component={Menu}>
                    <Route index component={Home} />
                    <Route path="about" component={About} />
                    <Route path="contact" component={Contact} />
                    <Route path="*" component={Error} />
                </Route>
            </Routes>
        </BrowserRouter>
    );
    
    export default App;
    
  4. Navigate Programmatically:

    Add a navigation example using useNavigate in Home.jsx:

    import { useNavigate } from "react-router-dom";
    
    const Home = () => {
        const navigate = useNavigate();
    
        return (
            <>
                <h2>Home Page</h2>
                <button onClick={() => navigate("/about")}>Go to About</button>
            </>
        );
    };
    
    export default Home;
    

This exercise will help you understand the basics of setting up and using React Router DOM for routing in React applications.