DEV Community

Jonnie Oak
Jonnie Oak

Posted on

How to fetch an external API with useEffect()

I just had a day full of headaches while trying to debug code while browsing StackOverflow, Reddit and Discord channels...

This post is for my future self but also for anyone who's having issues making external API calls in React. Specifically using fetch inside of useEffect.

TLDR: This is how you do it.

    const fetchWeather = async (url) => {
        const response = await fetch(url)
        const json = await response.json()
        setForecast({ data:json, loading:false })
    }

    useEffect(() => {
        if (search !== '') {
            fetchWeather(url)
        }
    }, [search])
Enter fullscreen mode Exit fullscreen mode

In this post I will be going over the following topics.

  1. Why useEffect for fetching an api?
  2. What's with the if statement inside the useEffect?
  3. What's happening inside fetchWeather?
  4. Why async/await?

Why useEffect for fetching an api?

  • useEffect is the functional version of ComponentDidMount, ComponentDidUpdate and ComponentWillUnmount
  • When making an API call, typically you don't want to make a call to the API with every render. In the example above, useEffect will invoke the callback (first argument) ONLY WHEN an item inside the array of dependencies (second argument) is changed

What's with the if statement inside the useEffect?

  • Without the if statement, useEffect will always run in the initial render
  • This was an issue in my code because the initial value for search (a dependency for the url) is ''. This results in a failed API call because there is a missing query to the API.
  • Skipping the initial render allows the user to input a query to the API which then re-renders the app with the API data.

What's happening inside fetchWeather?

  1. fetchWeather takes a url as an argument
  2. It then uses fetch to make an http request with the url
  3. Next line parses the http response into json
  4. setForecast updates the forecast state with the new data and also sets loading to false so that the data can be rendered

Why async await?
Fetch is promise based so you have to "await" for the promise to be resolved before moving on to the next line of code. E.g. you can't parse the response to json until the response is resolved. Another option is to use .then() and .catch() syntax to perform actions after a promise is resolved.

Top comments (1)

Collapse
 
aalphaindia profile image
Pawan Pawar

Interesting!