Using the useHistory Hook to Redirect After a Fetch Request in React

…err, this isn’t the blog you’re looking for … ?

React Router Setup

Install and Import Routing

Let’s start with some basics. First, make sure you’ve installed react-router-dom:

npm install react-router-dom
src/App.jsimport React from 'react';
import {
BrowserRouter as Router,
Switch,
Route
} from 'react-router-dom';
const App = () => {
return(
<>
App goes here
</>
)
}

Building out Routes and Components

Now, for the purposes of this example, let’s suppose

  1. we have an About page and component
  2. we have a component that we’ll use to display our daily-thoughts, called DailyThoughts
  3. we have a component called DailyThoughtForm that we can use to submit data for a new daily-thought
  4. we want to create routes for each of the components we are going to display, one for About, one for DailyThoughts, and one for DailyThoughtForm

This App’s Components (to Which We’ll Route)

For 1.–3.:

src/App.jsimport React from 'react';
import {
BrowserRouter as Router,
Switch,
Route
} from 'react-router-dom';
import About from './components/About'
import DailyThoughts from './components/DailyThoughts'
import DailyThoughtForm from './components/DailyThoughtForm'
const App = () => {
return(
<>
<About />
<DailyThoughtForm />
<DailyThoughts />
</>
)
}

Adding the Navbar and Links

For 4., let’s add in routes and a Navbar component in a header, too.

src/App.jsimport React from 'react';
import {
BrowserRouter as Router,
Switch,
Route
} from 'react-router-dom';
import About from './components/About'
import DailyThoughts from './components/DailyThoughts'
import DailyThoughtForm from './components/DailyThoughtForm'
import Navbar from './components/Navbar'
const App = () => {
return(
<Router>
<header>

<Navbar />
</header>

<Switch>
<Route exact path="/">
<About />
</Route>
<Route exact path="/dailythoughts/new">
<DailyThoughtForm />
</Route>
<Route exact path="/dailythoughts">
<DailyThoughts />
</Route>
</Switch>
</Router>
)
}
src/components/Navbar.jsimport { NavLink } from 'react-router-dom'const Navbar = () => { const link = {
padding: '12px',
margin: '0 6px 6px',
background: 'teal',
textDecoration: 'none',
color: 'white',
display: 'flex',
justifyContent: 'center',
flex: 1
}
return(
<div className="navbar">
<NavLink
to="/"
exact
style={link}
activeStyle={{background: "lightgreen", color: "black"}}
>
About
</NavLink>
<NavLink
to="/dailythoughts"
exact
style={link}
activeStyle={{background: "lightgreen", color: "black"}}
>
Daily Thoughts
</NavLink>

<NavLink
to="/dailythoughts/new"
exact
style={link}
activeStyle={{background: "lightgreen", color: "black"}}
>
New Daily Thought
</NavLink>
)
}
  • Now we have a Navbar that directs to each of the different components and emulates a change in webpages.
  • To do this, we use a NavLink and specify the route, which will match the route we have in our App’s Router

Fetching Data and Storing in State with useEffect and useState

For 5., let’s add in a fetch request and state to retrieve all of the daily-thoughts we already have stored in our API database:

src/App.jsimport React, { useState, useEffect } from 'react';
import {
BrowserRouter as Router,
Switch,
Route
} from 'react-router-dom';
import About from './components/About'
import DailyThoughts from './components/DailyThoughts'
import DailyThoughtForm from './components/DailyThoughtForm'
import Navbar from './components/Navbar'
const App = () => { const [dailyThoughts, setDailyThoughts] = useState([])

useEffect(() => {
fetch('https://mythoughtsapi.com/dailythoughts')
.then(resp => resp.json()
.then(returnedDailyThoughts => {
setDailyThoughts(returnedDailyThoughts)
}
}, [])
return(
<Router>
<header>
<Navbar />
</header>

<Switch>
<Route exact path="/">
<About />
</Route>
<Route exact path="/dailythoughts/new">
<DailyThoughtForm />
</Route>
<Route exact path="/dailythoughts">
<DailyThoughts dailyThoughts={dailyThoughts}/>
</Route>
</Switch>
</Router>
)
}
  • Here, the useEffect hook will run after the initial mounting and rendering of App. That’s what the [] second argument in useEffect ensures.
  • We also are setting the returned data of saved daily posts in our component’s state of dailyThoughts, using setDailyThoughts after the data is returned.
  • We then make sure to pass down the dailyThoughts state to the DailyThoughts component, which will display each daily-thought for us.
  useEffect(() => {
fetch('https://mythoughtsapi.com/dailythoughts')
.then(resp => resp.json()
.then(returnedDailyThoughts => {
setDailyThoughts(returnedDailyThoughts)
}
}, [])
...
<DailyThoughts dailyThoughts={dailyThoughts}/>
...

Using the useHistory Hook to Reroute after Fetching

Rerouting City Diagram
Photo by José Martín Ramírez Carrasco on Unsplash
src/App.jsimport React, { useState, useEffect } from 'react';
import {
BrowserRouter as Router,
Switch,
Route
} from 'react-router-dom';
import About from './components/About'
import DailyThoughts from './components/DailyThoughts'
import DailyThoughtForm from './components/DailyThoughtForm'
import Navbar from './components/Navbar'
const App = () => { let history = useHistory(); const [dailyThoughts, setDailyThoughts] = useState([])

useEffect(() => {
fetch('https://mythoughtsapi.com/dailythoughts')
.then(resp => resp.json()
.then(returnedDailyThoughts => {
setDailyThoughts(returnedDailyThoughts)
history.push('/dailythoughts')
}
}, [])
return(
<Router>
<header>
<Navbar />
</header>

<Switch>
<Route exact path="/">
<About />
</Route>
<Route exact path="/dailythoughts/new">
<DailyThoughtForm />
</Route>
<Route exact path="/dailythoughts">
<DailyThoughts dailyThoughts={dailyThoughts}/>
</Route>
</Switch>
</Router>
)
}

Set the Variable

  • We first set a variable for the useHistory hook. Here, we can just call it history:
let history = useHistory();

Use the .push Method

  • Then, wherever we want to cause a redirect in our app, whether that is after a fetch request—or after checking something like whether the use is logged in and authorized—we can simply use our variable + the .push(<route>)method to redirect to whatever route we’d like.
  ...
useEffect(() => {
fetch('https://mythoughtsapi.com/dailythoughts')
.then(resp => resp.json()
.then(returnedDailyThoughts => {
setDailyThoughts(returnedDailyThoughts)
history.push('/dailythoughts')
}
}, [])
...
  • Here, we redirect to the '/dailythoughts' route, which will take our user to the the route that displays our <DailyThoughts/> component:
    ...
<Route exact path="/dailythoughts">
<DailyThoughts dailyThoughts={dailyThoughts}/>
</Route>
...

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
David Ryan Morphew

David Ryan Morphew

10 Followers

I’m very excited to start a new career in Software Engineering. I love the languages, frameworks, and libraries I’ve already learned / worked with (Ruby, Rails,