DEV Community

Cover image for The React useEffect hook!
Barkley Santo
Barkley Santo

Posted on

The React useEffect hook!

Typically, when building a web application, we're using an API of some sort. We use that API to perform CRUD operations (Create, Read, Update, Delete) in our app depending on what actions our user is taking.

For example, if we want to fetch a random image of a dog from the DOG API 🐶, our typical fetch would look like this:

fetch("https://dog.ceo/api/breeds/image/random")
    .then(res => res.json())
    .then(data => console.log(data))
Enter fullscreen mode Exit fullscreen mode

Then, once we check our developer console, we can see that response object in JSON format after we've cleaned the data.

{message: "https://images.dog.ceo/breeds/terrier-irish/n02093991_3243.jpg", status: "success"}
Enter fullscreen mode Exit fullscreen mode

Now, in React we use State which is a built-in React object that is used to contain data or information about the component.

So now that we have our fetch API set up, let's store the response in our state! Check out the code below 😎

import React from "react"

export default function App() {
    const [dogData, setDogData] = React.useState({})


    fetch("https://dog.ceo/api/breeds/image/random")
    .then(res => res.json())
    .then(data => setDogData(data))

    return (
        <div>
            <pre>{JSON.stringify(dogData, null, 2)}</pre>
        </div>
    )
}
Enter fullscreen mode Exit fullscreen mode

Cool! So now it looks like we're making a fetch to the API, storing it as our new State and then re-rendering the component with its new state ♽!

But there's an issue…check out this statement from the React.js docs.

Image 1

This can get us into trouble right now. What's actually happening in our code now is that our component is making a fetch from the API, setting the state of the component, and then renders an updated component with its new state. Once that updated component is rendered, it runs the same fetch API request again, updates the state renders an updated component that makes a new fetch again, so we're stuck in an infinite loop, check out the GIF below.

Gif1

Now for the crux of this guide, the useEffect hook! Here it is implemented into our code:

    useEffect(() => {
        fetch("https://dog.ceo/api/breeds/image/random")
        .then(res => res.json())
        .then(data => setDogData(data))
    }, []);
Enter fullscreen mode Exit fullscreen mode

This hook takes in 2 arguments.

useEffect([callback], [dependency])
Enter fullscreen mode Exit fullscreen mode

The first one is a callback function, in this case it's our fetch request. The second argument (conceptually) is our dependencies, here, it's just an empty array because right now we don't have any dependencies.

If we omit the empty array as our second argument, our component will get stuck in its infinite loop again, so let's keep it there!

With this piece of code, we can ensure the fetch request happens only once, and we're successfully able to update our state with the data retrieved from the fetch, boom!

There you have it, a simple use-case for this hook, but an important one nonetheless.

Should you have any questions or any additional info to share, please reach out! Anything to help me improve these guides is helpful 💪🏾

Top comments (0)