The react library provides a single-page application (SPA), the web page won’t be reloaded, and only part may change based on the URL state. React routing uses the React-router-dom package to allow us to navigate between different content as the user navigates around.
For each navigation to URL, the react-router has to know which component should be rendered without refreshing the page.
We have three objectives behind this tutorial, first will learn how to configure react routing and second will implement react route using react router 6 packages. Last how we can retrieve route params at routed component. Let’s get started.
Difference ways of using react routing?
React Routing helps us to create Single Page Applications in Angular. In an application we may have many components, routing helps us to navigate between the different views that correspond to the component.
Name | Package |
react-router-dom | The react-router-dom package contains bindings for using React Router in web applications. The weekly download of 4,997,280 and 166 kB sizes. |
react-router | The react-router package is the heart of React Router and provides all the core functionality for both react-router-dom and react-router-native. The weekly download of 5,312,949 and 453 kB sizes. |
react-router-native | It is used for web applications design. |
In react web applications, most react developers use react-router-dom for reacting routing. We’ll use the react router 6 in our example.
React Routing basic example
Let’s take an example to demonstrate how we can implement react basic routing example using the react-router-dom 6 version package. Let’s create react project, and here is a screenshot of our first example.
Step for react routing configuration
Step1: Let’s first create react application by running the following command in the terminal.
npx create-react-app my-app
Step2: Install react-router-dom in our application.
We are using react-router-dom for our react-router example. Let’s install react-router-dom packages in our application.
npm i react-router-dom --save
Step 3: Create pages for routing
Create a few pages to demonstrate react routing example, in our case let’s create two pages in the pages folder in the src folder.
- About page
- Contact page
In src/pages/AboutPage.jsx add following code.
const AboutPage = () => {
return (
<div>
<h3>About pages goes here</h3>
<p>
Lorem Ipsum is simply dummy text ...
</p>
</div>
)
}
export default AboutPage
Do the same for the contact page.
Configure react routing in App.js file
In the App.js component, we configure routing for different components, we are setting the home page, about, and contact page with different URLs.
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Navigation from './components/shared/Navigation';
import AboutPage from './pages/AboutPage';
import ContactPage from './pages/ContactPage';
const App = () => {
return(
<Router>
<Navigation />
<Routes>
<Route exact path="/" element={
<div className='container'>
<h2>Home page</h2>
</div>
} />
<Route path="/about" element={<AboutPage />} />
<Route path="/contact" element={<ContactPage />} />
</Routes>
</Router>
)
}
export default App;
The App.js is the root component, here we configure react routing setting. Let’s discuss what we are doing.
- We need to import BrowserRouter, which is the root component where we wrapped all route configuration and import it from react-router-dom.
- Also import Routes, Route from react-router-dom.
- Import all pages or components, where we want to configure routing.
- Wrap all Route components inside the Routes component.
- In each Route component, we have a path attribute to set the path and an element attribute to link the route to a particular component or page.
Where URL match to particular path attribute will display its corresponding element or page. We use the Link component to display our page links in the header and Route elements to conditionally display page components depending on the matched URL. Now let’s create a header or navigation component to add a link to the route.
We have used attribute exact on Route component for path=”/”, this is need as to access path after slash / like /about and /contact. It says exactly matches a location or path when rendering inside the Routes component.
Component | Description |
BrowserRouter | It is a wrapper for all routing configurations. BrowserRouter uses HTML5 history API to keep our user interface in sync with the URL |
Route | This route component specifies what specific component we want to render to it. |
Types of Routers in react-router-dom
The react-router-dom support three different types of routers. The only difference between them is the part of the URL that they’re going to look at when deciding what content to show on the screen. Again the main difference between these is the part of the URL that each router is going to use to track what content the user is trying to view.
- Browser router: This is the most popular and used among them, we had already seen is example above.
- Hash Router: In hash, the router automatically puts a little hash character into the URL and then automatically tries to reflect the current path after that hash character.
- Memory Router: URL is not used at all to track navigation. The memory router keeps the URL changes in memory, not in the user browsers.
Create Navigation or header component
We have successfully configured routing, let’s create a Navigation component inside the src/components/shared folder. Let’s create Navigation.jsx and add the following react-router Link component to the link URL.
import { Link } from 'react-router-dom';
const Navigation = () => {
const navStyle = {
margin: 0
}
return (
<>
<nav style={navStyle}>
<ul className='flex items-center'>
<li className='ml-5'>
<Link to="/">Home</Link>
</li>
<li className='ml-5'>
<Link to="/about">About</Link>
</li>
<li className='ml-5'>
<Link to="/contact">Contact</Link>
</li>
</ul>
</nav>
</>
)
}
export default Navigation
In Link, we can also use.
<Link to={{ pathname='/persons', search: 'sort=name' }}>
We get
localhost:3000/persons?sort=name
How to add Active link in react-router link
<Link>
component no longer support the activeClassName
or activeStyle
properties. In react, router dom has a special component called <NavLink> that allows us to add the activeclassname attribute to apply the CSS class name on the active link.
Let’s replace the Link component with NavLink and we also need to import NavLink from react-router-dom.
import { NavLink } from 'react-router-dom';
import './navigation.css';
const Navigation = () => {
return (
<div className="header-container">
<h2>Logo</h2>
<nav>
<ul>
<li>
<NavLink to="/" activeclassname="active" className="link">
Home
</NavLink>
</li>
<li>
<NavLink to="/about" activeclassname="active" className="link">
About
</NavLink>
</li>
<li>
<NavLink to="/contact" activeclassname="active" className="link">
Contact
</NavLink>
</li>
</ul>
</nav>
</div>
)
}
export default Navigation
We have added class name as active on activeClassName, you can add any name of your choice like selected or any other. Now we can add CSS style for an active link in the index.css file
.active {
.header-container {
background-color: cornflowerblue;
width: 100vw;
margin: 0;
display: flex;
justify-content: space-between;
padding: 0 10px;
}
.active {
color: cornflowerblue;
font-weight: bolder;
padding: 8px;
background: white;
border-radius: 5px;
}
nav {
margin-right: 20px;
}
ul {
list-style: none;
}
li {
display: inline-block;
margin: 0 5px;
text-decoration: none;
}
.link {
text-decoration: none;
}
React router params
When working with real-life applications we need to add dynamic data to our URL path. We can pass data in URL, suppose we have /books URL and post with id like /books/id. In both cases, we are navigating to the same or different components, and the second one with on dynamic value.
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
...
const App = () => {
return(
<Router>
<Navigation />
<Routes>
<Route exact path="/" element={
<div className='container'>
<h2>Home page</h2>
</div>
} />
<Route path="/about" element={<AboutPage />} />
<Route path="/books" exact element={<BooksPage />} />
<Route path="/books/:id" element={< BookPage />} />
</Routes>
</Router>
)
}
export default App;
How to get react-router query params from URL?
In react-router-dom, we can use the useParams hooks to get the id value. In our BookPage component let import useParams from react-router-dom.
import { useParams } from "react-router-dom";
...
const BookPage = () => {
const params = useParams();
console.log(params.id);
// Add code to use params.id
...
}
React router redirect
In React router dom version 6 doesn’t support the Redirect component, we can use the Navigation component from the react-router-dom package.
import { Navigate, useNavigate } from 'react-router-dom';
function SomeComponent {
const navigate = useNavigate();
if (status === 404) { // use either Navigate to redirect to component of your choice
return <Navigate to='/notfound' />
}
...
const someFunction = () => {
navigate('/about'); // OR use useNavigate to redirect to particular page
}
}
How to use react-router nested routes
We might want to add nested routes in react, we can easily use it by using the react-router-dom component in our App.js and child components. To make a nested route inside the Products to Cloths component. To access localhost:3000/products/cloths
Step 1: Create the main route of the Product inside our App.js file
...
<Routes>
<Route path=/product/*' element={<Products />} />
....
</Routes>
Products
We need to add component/* at the end of the main route path otherwise, it will not work
Step 2: Add nested route inside Product to child component cloths
Now inside our child component of App that is the Product component let’s add a nested route.
import { Routes, Route } from 'react-router-dom';
const Product = () => {
.....
return(
<>
<h1>Product details page</h>
......
<Routes>
<Route path='cloths' element={<Cloths />}/>
</Routes>
Or
<Routes>
<Route
path='/cloths'
element={<h1>Show only when products/cloths</h1>} />
</Routes>
</>
)
}
React back button state
We can use the useNavigate hook to keep the back button state. To move back to the previous page, we have can use the useNavigate hooks.
import { useNavigate } from 'react-router-dom';
....
<button onClick={ () => { navigate(-1) }}>Back</button>
React 404-page example
When users route to a page that doesn’t exist, then we have to redirect to 404 pages not found. Here we have to follow this step. Here is a screenshot of React 404-page template example.
Step 1: Create react 404-page template
Let’s create page NotFound.jsx in the src/pages folder and add the following code for react 404-page template example.
import { FaHome } from 'react-icons/fa'
import { Link } from 'react-router-dom'
function NotFound() {
return (
<section class="page_404">
<div class="container">
<div class="row">
<div class="col-sm-12 ">
<div class="col-sm-10 col-sm-offset-1 text-center">
<div class="four_zero_four_bg">
<h1 class="text-center ">404</h1>
</div>
<div class="contant_box_404">
<h3 class="h2">
Look like you're lost
</h3>
<p>the page you are looking for not found!</p>
<Link className='btn btn-primary btn-lg' to='/'>
<FaHome className='mr-2' />
Back To Home
</Link>
</div>
</div>
</div>
</div>
</div>
</section>
)
}
export default NotFound
We need to add style for pages not found in the index.css file
/*======================
404 page
=======================*/
.page_404{
padding:40px 0;
background:#fff;
font-family: 'Arvo', serif;
}
.page_404 img{ width:100%;}
.four_zero_four_bg{
background-image: url(https://cdn.dribbble.com/users/285475/screenshots/2083086/dribbble_1.gif);
height: 400px;
background-position: center;
}
.four_zero_four_bg h1{
font-size:80px;
}
.four_zero_four_bg h3{
font-size:80px;
}
.link_404{
color: #fff!important;
padding: 10px 20px;
background: #39ac31;
margin: 20px 0;
display: inline-block;
}
.contant_box_404{
margin-top:-50px;
}
Step 2: Define route configuration for React 404 page not found.
In the App.js file, we need to add configuration for react 404 page.
...
<Router>
...
<Route path="/notfound" element={ <NotFound />} />
<Route path="/*" element={ <NotFound />} />
</Router>
....
In our application, we might get errors while calling remote API like 404 then we might navigate to a page not found.
// some API call error
if (response.status === 404 ) {
window.location = '/notFound'
}
Related articles