This post will quickly go over how to make use of the useEffect hook in React to retrieve data from an API.
This post assumes that you have a general understanding of how to fetch/retrieve data from an API as well as the fundamentals of React and React Hooks.
Our Component
Here we have a simple component.
import React from 'react';
import './App.css';
function App() {
return (
<div className="App">
</div>
);
}
export default App;
The component will be responsible for displaying an image of a random dog that is received from the API that we are fetching from. To do this, we'll need to:
- Import useState and useEffect
- Create our dogImage variable as well as the setDogImage function via useState
- Create out useEffect function — this is where we'll perform our fetch
- Within our useEffect function we'll use setDogImage to.. well... set dogImage to the image url that we received
- Use dogImage as the src for our image so that we can display the random dog
The API
The API that we're using has a few different endpoints that we can use, but for this simple example we'll just use the random image endpoint. This endpoint will simply return an object containing a message key and status key, we're only concerned about the message key in this simple example. The message key will contain the url that we'll use as the source for our image.
Putting it Together
// 1. Import *useState* and *useEffect*
import React, {useState, useEffect} from 'react';
import './App.css';
function App() {
// 2. Create our *dogImage* variable as well as the *setDogImage* function via useState
// We're setting the default value of dogImage to null, so that while we wait for the
// fetch to complete, we dont attempt to render the image
let [dogImage, setDogImage] = useState(null)
// 3. Create out useEffect function
useEffect(() => {
fetch("https://dog.ceo/api/breeds/image/random")
.then(response => response.json())
// 4. Setting *dogImage* to the image url that we received from the response above
.then(data => setDogImage(data.message))
},[])
return (
<div className="App">
{/* 5. Using *dogImage as* the *src* for our image*/}
{dogImage && <img src={dogImage}></img>}
</div>
);
}
export default App;
If our message returned an array of urls, like this:
// API Used: https://dog.ceo/api/breeds/image/random/3
// Returns:
{
"message": [
"https://images.dog.ceo/breeds/setter-irish/n02100877_1453.jpg",
"https://images.dog.ceo/breeds/buhund-norwegian/hakon3.jpg",
"https://images.dog.ceo/breeds/dane-great/n02109047_31049.jpg"
],
"status": "success"
}
We could do the following:
// 1. Import *useState* and *useEffect*
import React, {useState, useEffect} from 'react';
import './App.css';
function App() {
// 2. Create our *dogImage* variable as well as the *setDogImage* function via useState
// We're setting the default value of dogImage to null, so that while we wait for the
// fetch to complete, we dont attempt to render the image
let [dogImage, setDogImage] = useState(null)
// 3. Create out useEffect function
useEffect(() => {
fetch("https://dog.ceo/api/breeds/image/random/3")
.then(response => response.json())
// 4. Setting *dogImage* to the image url that we received from the response above
.then(data => setDogImage(data.message))
},[])
return (
<div className="App">
{/* 5. Returning an img element for each url, again with the value of our src set to the image url */}
{dogImage && dogImage.map((dog) => <img width={"200px"} height={"200px"} src={dog}></img>)}
</div>
);
}
export default App;
And thats that! You can view the live demo of this and explore the code yourself on this Replit.
As always, refer to the docs for more info:
MDN — Fetch
Feel free to reach out here or on my socials for any questions, suggestions, or to say hello 👋
Top comments (7)
Wow thanks, I have been having issue with fetching api but this post help me resolve this issue
This is completely broken with the release of React 18 and officially for the versions before not the correct way. You need te create a cleanup function.
e.g.
great answer thanks a lot
Yo, wanted to learn this from a while. Just found this ! amazing job dude !
Has anyone else ran into an infinite loop calling the API?
I basically did everything in this post, however the API kept getting called countless times while I'm on that page.
You better add a catch block, right?
you have probably added the state variable in the dependency array and so the use effect is changing the state of the variable which is causing the use effect to be called recursively . Hope u got the point