DEV Community

Cover image for React: Fetch Data from API with useEffect
Anthony DiPietrantonio
Anthony DiPietrantonio

Posted on

React: Fetch Data from API with useEffect

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;
Enter fullscreen mode Exit fullscreen mode

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:

  1. Import useState and useEffect
  2. Create our dogImage variable as well as the setDogImage function via useState
  3. Create out useEffect function — this is where we'll perform our fetch
  4. Within our useEffect function we'll use setDogImage to.. well... set dogImage to the image url that we received
  5. 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;
Enter fullscreen mode Exit fullscreen mode

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"
}
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

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

React Hooks

Dog API

Feel free to reach out here or on my socials for any questions, suggestions, or to say hello 👋

Top comments (7)

Collapse
 
beter_call_paul profile image
BETTER CALL PAUL ✪

Wow thanks, I have been having issue with fetching api but this post help me resolve this issue

Collapse
 
mwitteveen profile image
mwitteveen

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.



  useEffect(
    let ignore = false
    () => {
    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 => {if(!ignore){setDogImage(data.message);})
    return () => {ignore=true}
  },[])
Enter fullscreen mode Exit fullscreen mode
Collapse
 
krakoss profile image
krakoss

great answer thanks a lot

Collapse
 
rushannotofficial profile image
Rushan S J

Yo, wanted to learn this from a while. Just found this ! amazing job dude !

Collapse
 
tarekbeb profile image
Tarek Al Beb

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.

Collapse
 
stamatisdeli profile image
Stamatis Deliyannis

You better add a catch block, right?

Collapse
 
faiqqazi profile image
FaiqQazi

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