Quick Summary:
If you are planning to create a multipage React website and want to leverage all the perks of the React library, then I have created this hands-on guide to get your hands on React Routing with Router hooks. Let’s go through this React Router Hooks tutorial and start learning!
Introduction
ReactJS is a front-end library based on Javascript, which helps us to create the user interface at our ease. And for managing the navigation of a multipage website, we’ll be needing a third-party library like React Router.
Thus, in this React Router tutorial, we’ll dig deep and understand routing in React.
What is React Routing?
React Routing is a process of showing various pages on their respective URL. Users can have the liberty to navigate the pages by manually writing the URL or clicking the element. You need to install the react-router library to enable the routing in the React application.
React Router library provides three packages:
react-router, react-router-dom, and react-router native.
The react-router offers you the core functionality; react-router-dom and react-router-native are dependent on your projects’ environment. One should use react-router-dom for website development and React-router-native for mobile application development.
How to install react-router-dom?
For installing React Router, you can use npm or yarn and run the following commands.
yarn add react-router-dom OR npm install react-router-dom
We have done the installation of the router successfully! Let’s move ahead to get some knowledge regarding the basics of React Router.
React Router: Fundamentals
Router Component
We have to wrap our < App > component with
So, let’s wrap the < App > component by importing the
// /src/index.js import React from "react"; import ReactDOM from "react-dom"; import App from "./App"; import { BrowserRouter as Router } from "react-router-dom"; ReactDOM.render( < Router > < App / > < /Router >, document.getElementById("root") );
By this, we can apply the routing to our entire application.
You are free to use BrowserRouter directly. I prefer to write it like this. The code written above will create the history object for the component.
Every < Router > component written for wrapping a parent component (here < App > component) will generate the stack of previous locations and keep the record of the current location (history.location).
Whenever the current location changes, the view re-renders, and you can see navigation between the pages.
There must be a question about how does the current location change?
Or what makes it update the current location?
Here is the answer, the history object consists of these two methods- history.push and history.replace.
On clicking the component history.push will invoke and < Redirect > component history.replace.
Link and Route Component
< Route > component is considered as an essential component in React Router. Its function is to render the UI whose current location matches the path (it is a prop under the Route component) of the route.
< Link > component is used for navigating between the pages. We can compare it to the < a > tag of the HTML; the only difference is that < a > refreshes the page, which we don’t need. Thus, we will use < Link > for navigating without refreshing the page.
Okay, so I believe we are good till here. Great! Let’s move ahead and make an application for the react-router example.
// /src/App.js import React from "react"; import { Link, Route, Switch } from "react-router-dom"; const Home = ( ) => ( < h2 >This is the Home page< /h2 > ); const About = ( ) => ( < h2 >This is an About page< /h2 > ); const Contact = ( ) => ( < h2 >This is the Contact Page < /h2 > ); const Products = ( ) => ( < h2 >This is the Products Page < /h2 > ); export default function App() { return ( < div > < nav > < ul > < li > < Link to="/" >Home< /Link > < /li > < li > < Link to="/about" >About< /Link > < /li > < li > < Link to="/contact" >Contact< /Link > < /li > < li > < Link to="/products">Products< /Link > < /li > < /ul > < /nav > { /* when the path prop will match the current URL these components will render */} < Route path="/" >< /Route > < Route path="/about" >< About/ >< /Route > < Route path="/contact" >< Contact/ >< /Route > < Route path="/products" >< Products/ >< /Route > < / div > ); }
Here we have four components – Home, About, Contact, and Products with their respective routes ( URL) /home, /about, /contact, and /products. The < Route > components consist of the logic for rendering the pages. < Link > components can be said as the < a > tag and are used for navigation. Whenever the prop path changes and matches the current URL, the matching route’s component renders.
Assume I’m on the Home page so that the prop path would be /home.
Now further, I clicked the About link. So, directly the prop path would change to /about from /home. Hence, it will check the < Route > component’s logic and render the < About / > component.
I have written the code in the file App.js, but as the components exceed more code lines, I’ll create separate components for each.
There’s a problem with this routing, though. Even if we switch the pages and click the link, we will always see the Home page. Whenever React Router checks its prop path, it will redirect to the component which is starting with / and thus it will always display the Home page because its path is / Assume I clicked the Products page. Now I’ll see both the Home page and Products page because / matches both / and /products.
To overcome this default behavior of react routing, we can use the prop exact in the < Route > component. Rewrite the < Route > component for the Home page.
< Route path="/" exact >< Home / >< /Route >
By updating the code as above, the Home page will render when it matches the exact route, i.e., /
We are done with the necessary explanation with a simple example of react routing. Now, assume that we have sub-categories of the products, i.e., product_one and product_two; how will we write the logic for its routing? In such a case, where we have sub-categories, we tend to use nested routing. Our next topic of the react router tutorial is Dynamic Nested Routing; let’s see what it has.
What is Dynamic Nested Routing?
For having your hands on Dynamic Nested Routing, we should first know
The recommended method of rendering something with a
So let’s discuss those methods-
- component: On using component, the router will create the React element, using React.createElement; whenever the URL will match, it will render the component. If you give a function that will return a component, it will create a new component at every render rather than updating it.
< Route path="/products" component={Products} / >
< Route path="/products" render={() => < Products / >} / >
So, this was the overview of how
Remember I gave you the scenario above for the sub-categories of products; we will take that as an example and understand the nested routing.
// /src/App.js import React from "react"; import { Link, Route, Switch } from "react-router-dom"; import Products from "./Products"; const Home = () => ( < h2 >This is the Home page< /h2 > ); const About = () => ( < h2 >This is an About page< /h2 > ); const Contact = () => ( < h2 >This is the Contact Page < /h2 > ); export default function App() { return ( < div > < nav > < ul > < li > < Link to="/" >Home< /Link > < /li > < li > < Link to="/about" >About< /Link > < /li > < li > < Link to="/contact" >Contact< /Link > < /li > < li > < Link to="/products" >Products< /Link > < /li > < /ul > < /nav > { /* when the path prop will match the current URL these components will render */} < Route path="/" >< Home/ >< /Route > < Route path="/about">< /Route > < Route path="/contact"> < /Route > < Route path="/products"> < /Route > < / div > ); }
I created a separate component for the Products to make it neat and clean.
Here’s the code for Products.js
// src/Products.js import React from "react"; import { Link, Route, useParams, useRouteMatch } from "react-router-dom"; const Item = ( ) => { const { name } = useParams(); return ( < div > < h3 >{name}< /h3 > < /div > ); } const Products = ( ) => { const { url, path } = useRouteMatch(); return ( < div > < ul > < li > < Link to={`${url}/product-one`}>Product One < /li > < li > < Link to={`${url}/product-two`} >Product Two < /li > < /ul > < Route path={`${path}/:name`} > < Item/ > < /Route > < /div > ); }; export default Products;
Here we have used the useRouteMatch hook in order to match URLs just like < Route >. As the documentation of React Routing have mentioned
The useRouteMatch hook either:
- takes no argument and returns the match object of the current < Route >
- takes a single argument, which is identical to props argument of matchPath.
If you have confusion regarding the useRouteMatch hook, you can console.log(useRouteMatch()) and clarify a few things.
< Route path={`${path}/:name`} > < Item / > < /Route >
We will not hard code the routings; instead, we will try to attempt dynamic routing. We will use a variable within the prop path and :product-name will be the path parameter that will find after /products until we come across another forward slash. We will further use the useParams hook for accessing the value in the
Okay, so far, we have covered Installation of React Router Dom, Basic and Dynamic Nested Routing in the react router tutorial, now it’s time to move ahead with the Router Hooks.
React Router Hooks
React Router hooks had made things a lot easier than before. Now the history, parameters, or location is accessible in a straightforward way. For React Router hooks, you must check that you are using the React version greater than or equal to 16.8.
Here are the React Router hooks, which we will discuss further –
- useHistory
- useParams
- useLocation
useHistory
The useHistory will help you for accessing the history instance for navigating purposes. So, now there’s no need to pull out the history from the prop; you can simply use the useHistory hook.
import { useHistory } from "react-router-dom"; const Contact = () => { const history = useHistory(); return ( <> < h2 >About< /h2 > < button onClick={() => history.push('/') } >Go to homepage < /button > > ) };
useParams
The useParam will return an object of URL parameter’s key/value pairs without using the prop.
import { BrowserRouter as Router, Route, Link, Switch, useParams } from "react-router-dom"; export default function App( ) { const name = 'James Ruso' return ( < Router > < div > < nav > < ul > < li >< Link to="/" >Dashboard< /li > < li >< Link to={`/about/${name}`} >About < /li > < /ul > < /nav > < Switch > < Route path="/" exact component={Dashboard}/ > < Route path="/about/:name" component={About}/ > < /Switch > < /div > < / Router > ); } const About = ( ) => { const { name } = useParams( ) return ( // props.match.params.name < > { name !== 'James Ruso' ? < Redirect to= " / " /> : null } < h2 >About {name} < /h2 > < Route component={Contact} / > < / > ) };
useLocation
The useLocation will return you the current location within the location object.
import { useLocation } from "react-router-dom"; const About = ( ) => { const { pathname } = useLocation(); return ( < > < h1>About< /h1 > < p >Here is the Current URL: {pathname}< /p > < / > )h };
Conclusion:
I hope your purpose of landing on this blog post to learn about React router hooks has been served. If you are looking for assistance with React routers to create and navigate between different URLs or need support to manage the transition between views and redirects, then get in touch with us today to embrace the power of React Router with Router Hooks. We have expert ReactJS developers who are well-versed in offering top-of-the-line ReactJS development services.