0% completed
Single Page Applications (SPAs) have revolutionized the way web applications are developed and experienced. They offer dynamic, fluid user interactions by loading a single HTML page and dynamically updating content based on user actions which eliminates the need for full-page reloads. This approach mimics desktop applications, delivering a smoother and faster user experience.
To create such applications, React Router is an indispensable tool. It provides powerful routing capabilities, allowing you to manage navigation seamlessly in your React application.
React Router is a library that enables routing and navigation within React applications. It allows the creation of dynamic, responsive navigation in SPAs, ensuring users can move between pages without reloading the browser.
The library's DOM-specific variant - React Router DOM, is tailored for web applications and contains DOM-centric APIs.
Traditional web apps often reload the entire page for every user interaction, which can feel slow and disruptive. SPAs load content dynamically, creating a faster experience.
React Router enables this by:
BrowserRouter
BrowserRouter wraps the entire application, managing the navigation and current location in the browser's address bar using URLs which comes in handy during navigation. It acts as the parent component that houses all the route components. All routes in the application must be declared within the <BrowserRouter>
.
To use the BrowserRouter, you'll need to import it from the react-router-dom
in your application's component.
Example:
import { BrowserRouter } from "react-router-dom"; function App() { return ( <BrowserRouter> {/* Routes will be defined here */} </BrowserRouter> ); }
Routes and Route
Routes acts like a parent and renders the first matching child route, which ensures that the correct component is displayed based on the current URL.
Route is a child component that consists of two attributes: path and element. A path can be any specified path name while the element attribute is the component that should be rendered. A route renders a specific component when the path specified matches a URL.
An application can have as many routes as it needs, and they must all be declared inside the Routes component.
Import Routes and Route from react-router-dom
and position it within the <BrowserRouter>
. Also, remember to import the individual components in order to use them in your file.
Example:
import { BrowserRouter, Routes, Route } from "react-router-dom"; import function App() { return ( <BrowserRouter> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> </Routes> </BrowserRouter> ); }
Nested Routes
Nested routes allow you to structure your app hierarchically. It allows routes to have children or sub-routes. For example, an e-commerce site might have a Products page with subcategories like Electronics and Clothing.
Example:
import { BrowserRouter, Routes, Route } from "react-router-dom"; function App() { return ( <BrowserRouter> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> <Route path="products" element={<Products />}> <Route path="electronics" element={<Electronics />} /> <Route path="clothing" element={<Clothing />} /> </Route> </Routes> </BrowserRouter> ); }
On navigating to the nested elements, the URL on the browser will be reading something like /Products/Electronics
and /Products/Clothing
.
Undefined Routes
There is a way to handle routes that do not exist in your application, just like an Error 404 page. To do this, create another component bearing a Not Found message and the route added.
Set the path name to a wildcard route (*) and pass the component as the element. Assuming we call the component PageNotFound, here is how it would be represented.
Example:
import { BrowserRouter, Routes, Route } from "react-router-dom"; function App() { return ( <BrowserRouter> <Routes> <Route path="/" element={<Home />} /> <Route path="products" element={<Products />}> <Route path="electronics" element={<Electronics />} /> <Route path="clothing" element={<Clothing />} /> </Route> <Route path="*" element={<PageNotFound />} /> </Routes> </BrowserRouter> ); }
Link and NavLink
The Link
component is used to create navigation links. Unlike traditional <a>
tags, Link
prevents page reloads. It has a to attribute which specifies where the Link will take the user after a click. Usually, it is the path to a component's page that is passed to the to attribute.
To use Link, you need to import Link from the react-router-dom
.
Example:
import { Link } from "react-router-dom"; function Navbar() { return ( <nav> <Link to="/">Home</Link> <Link to="/about">About</Link> </nav> ); }
The NavLink
component extends Link
by adding conditional styling during user interactions. It has a class attribute and this makes it more versatile than Link. The class attributes that can be used on the NavLink are active
, isPending
, and isTransitioning
.
Example:
<NavLink to="/" activeClassName="active">Home</NavLink>
Outlet
The Outlet
component is used in parent routes to render child components dynamically.
Example:
function Products() { return ( <> <h1>Products</h1> <Outlet /> </> ); }
Here, the <Outlet />
will render the content of any nested routes that match.
useNavigate Hook
The useNavigate
hook returns a function that enables programmatic navigation between routes.
There are several ways to use the navigate function in your application.
First, we need to import the useNavigate hook and initialize it as navigate.
import { useNavigate } from "react-router-dom"; export default function Homepage() { const navigate = useNavigate(); return ( <> <h1>This is the Homepage</h1> </> ); }
We can also use navigate in the following ways in our application:
<button onClick={() => navigate("/categories")}>Go to Categories</button>
<Link to={navigate("/categories")}>Go to Categories</Link>
<Link to={navigate(-1)}>Go one step backwards</Link>
useParams Hook
useParams retrieves dynamic route parameters and returns an object of the dynamic params gotten from the current URL matched by the Route's path. The parent routes pass all params to their child routes.
Example:
function ProductDetail() { const { id } = useParams(); return <h1>Product ID: {id}</h1>; }
Having learnt all these concepts of the react router, we'll be build a simple navigation system. It would include a navigation bar with components routes rendered just below.
This is what we would like to achieve in this section:
Now, we set out to implement the navigation system by following these steps:
Create necessary components
Looking at our navigation system picture, we would need four components: The Home, About, Products and PageNav component.
PageNav is the name we'll call our component that would act as our navigation bar. A navigation bar is a section of a webpage that houses all the links to navigate different parts of an application.
These are the components and their respective JSXs:
//in Home.js export default function Home(){ return <h1>This is the Home page</h1> } //in About.js export default function About(){ return <h1>This is the About Page</h1> } //in Products.js export default function Products(){ return <h1>This is the Products page</h1> }
Configuring the PageNav Component
The PageNav would only include Links to the various components - Home, About and Products. As we've learnt, the Link component acts like the HTML <a>
element.
In our PageNav component, we would have this:
import { Link } from "react-router-dom"; export default function PageNav(){ return( <div> <Link to="/">Home</Link> <Link to="/about">About</Link> <Link to="/products">Products</Link> </div> ) }
Here,
react-router-dom
.Configuring our App Component
In this component, we put it all together, the App component serves as the central hub for all the components. We would structure how we want our four components to appear on our webpage here.
The four components are not the only pieces of our application's puzzle. We need to use some other essential players of the react-router-dom
such as the BrowserRouter, Routes and Route.
This is how we go about it:
import { BrowserRouter, Routes, Route } from 'react-router-dom'; import PageNav from './PageNav'; import Home from './Home'; import About from './About'; import Products from './Products'; function App() { return ( <BrowserRouter> <PageNav /> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> <Route path="/products" element={<Products />}/> </Routes> </BrowserRouter> ); } export default App
In this code,
BrowserRouter
, Routes
and Route
components from the react-router-dom
.BrowserRouter
to wrap all our intended components and routes.Routes
component which houses the individual routes comes next.Route
is called with a specified path and an element attribute of the component.This is all we have to do to have our single-paged navigation application.
Output
Keep an eye on the url part of the browser at the top and notice the change in the app's url as we navigate. The dynamic, seamless, and instantaneous navigation that react-router offers — making applications feel like a single page, is why it is popular in building applications today.
.....
.....
.....