October 4, 2023

React Router - Link in react-router-dom

This post Routing in React With Examples gives an introduction of routing in Reactjs using React Router. Generally, in an application you will have several navigational links and a navigation menu to route to different pages. In this post we'll see how to use <Link> in React Router for navigation.

Link in react-router-dom

While creating HTML pages you must have used anchor tags with href attribute (<a href=”/”>) for navigation.

A <Link> element in react-router-dom also renders an <a> element with a href that points to the resource it's linking to. But you should not use anchor tag directly in your React app because that will result in a full-page load. <Link> has the functionality for client-side routing and that’s what you should use.

Navigating to another page using Link - React Example

Link has a "to" attribute using which you can specify the pathname. For example, from home page you want to give a link for navigating to about page.

src\components\Routes\home.js

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

const Home = () => {
    return (
        <>
            <h2>This is home page</h2>
            <Link to="/about">Go to About page</Link>
        </>
    )
}

export default Home;

src\components\Routes\about.js

const About = () => {
    return <h2>This is a router demo</h2>
}
export default About;

Route definition

src\components\Routes\route.js

import { createBrowserRouter } from "react-router-dom";
import About from "./about";
import Home from "./home";

export const router = createBrowserRouter([
    {path: "/", element: <Home /> },
    {path: "/about", element: <About />} 
])

Providing the routes

Provide the route definition to your application using the <RouteProvider> component.

import { RouterProvider } from 'react-router-dom';
import { router } from './components/Routes/route';

function App() {
  return <RouterProvider router={router}></RouterProvider>
}

export default App;

Now if you access the root path by accessing http://localhost:3000/ you should also see a link to About page. Clicking that link should navigate you to About page.

Link in react-router-dom

Navigation menu using Link - React Example

Another use of Link is to create a navigation menu so that user can easily navigate the pages. You may think that by creating a page with a navigation menu and adding it to App.js before the <RouterProvider> should do the job. But it is a little more involved than that.

Let’s first try to create a navigation page and add that to App.js to see what is the problem.

src\components\Routes\navigation.js

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

const Navigation = () => {
    return(
        <>
            <nav className="navbar navbar-expand-lg bg-dark navbar-dark">
                <div className="container-fluid">
                    <button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
                        <span className="navbar-toggler-icon"></span>
                    </button>

                    <div className="collapse navbar-collapse" id="navbarNav">
                        <ul className="navbar-nav">
                            <li className="nav-item"><Link className="nav-link" to="/">Home</Link></li>
                            <li className="nav-item"><Link className="nav-link" to="/about">About</Link></li>
                        </ul>
                    </div>
                </div>
            </nav>
        </>
    );
}

export default Navigation;

Note that Bootstrap 5 classes are used here for styling the navbar.

Want to know how to add Bootstrap to your React application, check this post- Installing Bootstrap in React

Now add it to App.js

function App() {  
  return (
    <>
      <Navigation />
      <RouterProvider router={router}></RouterProvider>
    </>
  );
}

export default App;

But running it will result in following error.

Cannot destructure property 'basename' of 'react__WEBPACK_IMPORTED_MODULE_0__.useContext(...)' as it is null.

This error comes because <Link> works when it is rendered with in the <RouterProvider> not next to it. That means the Navigation component we have just created should be known to the Route definition (and be a part of Route definition).

How it should be done is to make the route, that points to Navigation, as parent component and the other routes as nested routes. With that change src\components\Routes\route.js file is as given below.

import { createBrowserRouter } from "react-router-dom";
import About from "./about";
import Home from "./home";
import Navigation from "./navigation";
export const router = createBrowserRouter([
    {path: "/", element: <Navigation />,
     children: [
        {path: "/", element: <Home /> },
        {path: "/about", element: <About />}
     ]
    },        
])

Note the use of children to specify another array of child routes.

That would also necessitate the use of <Outlet /> in Navigation to render the child route’s element.

src\components\Routes\navigation.js

import { Link, Outlet } from "react-router-dom"

const Navigation = () => {
    return(
        <>
            <nav className="navbar navbar-expand-lg bg-dark navbar-dark">
                <div className="container-fluid">
                    <button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
                        <span className="navbar-toggler-icon"></span>
                    </button>

                    <div className="collapse navbar-collapse" id="navbarNav">
                        <ul className="navbar-nav">
                            <li className="nav-item"><Link className="nav-link" to="/">Home</Link></li>
                            <li className="nav-item"><Link className="nav-link" to="/about">About</Link></li>
                        </ul>
                    </div>
                </div>
            </nav>
            <Outlet />
        </>
    );
}

export default Navigation;

src\App.js

import { RouterProvider } from 'react-router-dom';
import { router } from './components/Routes/route';

function App() {
    return <RouterProvider router={router}></RouterProvider>
}

export default App;

As you can see there is no need to add <Navigation> as a separate component in App.js

Nav menu using Link - React

That's all for the topic React Router - Link in react-router-dom. If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment