This tutorial explores the useHistory
hook of react-router-dom
, which is a special package of React that allows us to make our app navigation robust and efficient.
react-router-dom
allows us to navigate through different pages on our app with/without refreshing the entire component. By default, BrowserRouter
in react-router-dom
will not refresh the entire page.
However, if you want your app to refresh on the click of any link or button, then you can set the forceRefresh
attribute to true
inside the BrowserRouter
of react-router-dom
, as follows:
<BrowserRouter forceRefresh={true} />
Let’s use npx create-react-app myapp
to create a simple react app and install react-router-dom
with the following command inside the terminal of our app.
npm i react-router-dom
Now, we will create a components folder in src directory
of our app, and create the following three components.
Home.js
About.js
ContactUs.js
We will import these components in App.js
in the following manner.
import React from 'react'
import './App.css';
import { BrowserRouter, BrowserRouter as Router,Redirect, Switch ,Route,Link} from 'react-router-dom';
import {Home} from './components/Home'
import {About } from './components/About'
import {ContactUs} from './components/ContactUs'
import {NotFound} from './components/NotFound'
function App() {
return (
<BrowserRouter>
<div className="App">
<h1>React Router Demo</h1>
<div className="navbar">
<Link to="/">Home</Link>
<Link to="/contact">Contact Us</Link>
<Link to="/about">About</Link>
</div>
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/contact">
<ContactUs />
</Route>
<Route path="/about">
<About />
</Route>
<Route path="*"><NotFound /></Route>
</Switch>
</div>
</BrowserRouter>
);
}
export default App;
For each component, we have defined a Link
that specifies the path and route. We have also defined a * path which will render the Not Found
component in case a random and undefined path is defined.
Now, suppose one of the routes, e.g. ‘Contact Us’, is a protected route. Suppose we need to redirect the user to that component only if they have logged in to our app; otherwise, they will be redirected back to the homepage.
For this purpose, we will create a login button on the App.js
file that will be false
by default, but a click on it will login the user. We will also declare a useState
hook where we will keep track of the state of the login button, as follows.
const [login,setLogin] = useState(false);
<button onClick={()=>setLogin(!login)}>{login ? "Login" : "Log out"}</button>
And in the ContactUs
component, we can define the redirect path based on the value of login button, as follows.
<Route path="/contact">
{login ? <ContactUs /> : <Redirect to="/" />}
</Route>
Now, we can see that if the user is logged in, only then they can visit the Contact Us page. Otherwise, they will be redirected to the homepage.
Another way of doing this is through the useHistory
hook.
In the Contact Us component, we will pass the login prop. Depending on the value of login, we will let the history.push
method render the correct component in the following manner.
import React from 'react'
import { useHistory, useEffect } from 'react-router-dom'
export const ContactUs = ({login}) => {
const history = useHistory();
useEffect(()=>{
if(!login){
history.push("/")
}
},[login,history]);
return (
<div>
This is the Contact Us Page
</div>
)
}
Also, remember to make the Contact Us route on App.js
a normal route before you import useHistory
in the respective component:
<Route path="/contact">
<ContactUs login={login}/>
</Route>
This was a simple explanation of Redirect
and useHistory
from React. We hope you find it useful.