React

How to asynchronously call APIs inside the useEffect hook?

In this article, we will learn how to make async requests in the useEffect hook. There are several cases where we would...

Written by Shivangi Rajde · 3 min read >
asynchronously call APIs inside the useEffect hook

In this article, we will learn how to make async requests in the useEffect hook. There are several cases where we would need to call the API asynchronously and use the data from that API for various purposes. We will learn about the ways in which we can use async and await calls to the API.

finger , finger icon, left, right png and psd - finger pointing icon PNG  image with transparent background | TOPpng

Demo

Note: We can’t attach the handler to the useEffect hook as the function passed to useEffect should not return anything except the cleanup effect function.

You might be having some questions in your mind, why would we require async calls to the API?

Generally, we make a mistake we assign the async keyword to the function that we used as the first argument in our useEffect hook. Generally, it is the correct way to declare any function async and have the await keyword inside that function. The function waits till the API request completes.

useEffect(async () => { 
    const fetchPosts = await axios.get( 
      "https://jsonplaceholder.typicode.com/posts" 
    ); 
    setPostList(fetchPosts.data); 
 }, []); 
Warning while assigning an async keyword to the first argument
Warning while assigning an async keyword to the first argument

This method of asynchronously calling any function is not recommended by the React team. Everything will work fine but a warning will be displayed in the console that states that “Effect callbacks are synchronous to prevent race conditions. Put the async function inside” As you can see in the image below, it also gives a piece of code as a suggestion so that we can follow it and use the best practices recommended by the react team.

useEffect(() => { 
  async function fetchData() { 
    // You can await here 
    const response = await MyAPI.getData(someId); 
    // ... 
  } 
  fetchData(); 
}, [someId]); // Or [] if effect doesn't need props or state

The main thing that we need to keep in mind is that we need to call a different function inside the first argument of the useEffect and declare that function as an async function. We can await for the function that we have called inside the useEffect hook.

There are some ways in which we can call/declare the function inside the useEffect hook. Let’s have a look at different ways in which we can use async functions inside the useEffect hook.

Method 1: Creating async function inside useEffect and calling immediately

In this method, we can create a function inside the first argument of the useEffect hook. For declaring any function as async we need to add the keyword “async” before the declaration of the function.

useEffect(() => {
    const fetchPosts = async () => {
      const res = await     axios.get("https://jsonplaceholder.typicode.com/posts");
      setPostList(res.data);
    };
    fetchPosts();
  }, []);
Creating async function inside useEffect and calling immediately
Creating async function inside useEffect and calling immediately

I have used an arrow function to declare a function and added the “async” keyword before the function definition. The await keyword is added before the get request so that we can wait for the response from the API.

We need to call the function exactly after the declaration of the function. The function we declared will be called and Axios will return a promise which will be stored in the “res” constant. We have already defined a const for saving our posts from the API so that we show all the posts as a list. We need to get the data from the response, so we will use our setter function of the useState hook which is “setPostList” which will only have the data instead of the promise.

Method 2: Declare a function outside useEffect and call it inside

In this method, we declare an async function inside our component but outside the useEffect hook. The shown below is the definition of the function in which we need to make async calls.

const fetchPosts = async () => {
    const res = await axios.get("https://jsonplaceholder.typicode.com/posts");
    setPostList(res.data);
  };
fetchPosts method
fetchPosts method

Now in our useEffect hook, we call the function that we declared outside our hook. All the asynchronous calls will be declared in the function “fetchPosts” we just need to call that function.

useEffect(() => {
    fetchPosts();
  }, []);
second method for useEffect hook
second method for useEffect hook

If you are getting confused that which method should be used from the first two methods, you can use either the one that you find simple and cleaner. There are no performance differences that would help us lean towards one of the methods.

Method 3: Using an anonymous self-invoking function

JavaScript has a valid syntax in which we don’t need to have variable declaration and the function can be invoked immediately after the declaration of the function. Such functions as also known as anonymous self-invoking functions as the functions are defined without the name.

Let’s have a look at how it gets defined and how are the functions invoked. Two arrows in the image below indicate the definition of the function, the body of the function is wrapped by the parenthesis and the parenthesis inside the box indicates that the function needs to be called immediately.

useEffect(() => {
    (async () => {
      const res = await axios.get("https://jsonplaceholder.typicode.com/posts");
      setPostList(res.data);
    })();
  }, []);
Method 3 for useEffect hook
Method 3 for useEffect hook

Here we have a function without name wrapped inside the parenthesis and it gets invoked immediately after the definition. It is not so that this method is faster, but it depends on the readability of the code the more readable code you find you can use that method.

Method 4: Promise approach

In this method, we will be using a package “Axios” for calling APIs. Calling API using Axios returns a promise. We can add a “then” statement after the API call so that the code inside our then block gets executed as soon as we get the response from the API. We can add multiple cascading then blocks in the sequence we want to perform the operations.

useEffect(() => { 
    axios.get("https://jsonplaceholder.typicode.com/posts") 
    .then(response => { 
      setPostList(response.data); 
    }); 
  }, []);
Method 4 for useEffect hook
Method 4 for useEffect hook

Here, we use the package Axios and use the method as per our requirement in this case we have used the get method to fetch the data from the API. After the HTTP method, we add our then block so that we can perform the operations inside it. In our case, we use the promise from the response and set the post list’s data to our postList state.

Summary

In this article, we learned about various ways of asynchronously calling the APIs in the useEffect hook. We also have the demo provided on the online playground stackblitz. Visit the link to have a look at the code.

Loading

2 Replies to “How to asynchronously call APIs inside the useEffect hook?”

  1. When we need to call multiple api , one after one and one api result to be passed in other api,
    I.tried it and its working but its givening warning dependncy of function to be include , abd when function in included , its run multiple times

Leave a Reply

Your email address will not be published. Required fields are marked *