Handle API Calls Using async await Inside the useEffect Hook in React

Handle API Calls Using async await Inside the useEffect Hook in React

If you are a fan of async await syntax, then you might try using it in useEffect hook in React, but it does not work as expected. In this article, we will see how to handle that.

Let’s write some code using promises first and then we will convert it to async-await. We will make an API call for displaying 10 random users.

useEffect(() => {
 axios.get('https://randomuser.me/api/?page=1&results=10&nat=us')
  .then(response => {
   setUsers(response.data.results);
 });
}, []);

Here's a Code Sandbox Demo.

In this useEffect hook, we have provided an empty array [] as the second argument so the code inside useEffect will run only once when the component is mounted which is a way to implement componentDidMount lifecycle method in react hooks.

Now, let’s convert the same code to async await syntax.

useEffect(async () => {
  const users = await axios.get("https://randomuser.me/api/?page=1&results=10&nat=us");
  setUsers(users.data.results);
}, []);

Here's a Code Sandbox Demo.

Here, we have made the useEffect callback function as async so we can use the await keyword inside it.

But, if you run the application, you will see a warning in the console.

Live Demo: https://cw964.csb.app/.

async_error.png

In React, every warning shown in red color should be fixed as it may affect the performance or the application behavior or it may be suggestion to improve your application.

The issue in the above code is that, when we declare any function as async, it returns a promise.

Take a look at the below code:

const getResults = async () => { return "Hello"; };

const App = () => {
 const result = getResults();
 console.log(result);

 return null;
};

Here's a Code Sandbox Demo.

If you open the console, you will see that, the result printed is not the string “Hello” but a promise.

To get the actual value, we need to attach .then handler to the function call like this:

const getResults = async () => { return "Hello"; };

const App = () => {
 getResults()
  .then(response => console.log(response));

  return null;
};

Here's a Code Sandbox Demo.

Now, we got the actual value Hello in the console.

But we can’t attach .then handler to the useEffect hook as function passed to useEffect should not return anything except cleanup effect function.

So there are some ways to fix this.

  • Create a separate async function outside useEffect and call it from the useEffect:
const getUsers = async () => {
 const users = await axios.get('https://randomuser.me/api/?page=1&results=10&nat=us');
 setUsers(users.data.results);
};

useEffect(() => {
 getUsers();
}, []);

Here's a Code Sandbox Demo.

  • Create a separate async function inside useEffect and call it from useEffect:
useEffect(() => {
  const getUsers = async () => {
    const users = await axios.get("https://randomuser.me/api/?page=1&results=10&nat=us");
    setUsers(users.data.results);
  };
  getUsers();
}, []);

Here's a Code Sandbox Demo.

  • Use an IIFE(Immediately Invoked Function Expression):
useEffect(() => {
 (async () => {
  const users = await axios.get("https://randomuser.me/api/?page=1&results=10&nat=us");
  setUsers(users.data.results);
 })();
}, []);

Here's a Code Sandbox Demo.

Thanks for reading!

Want to learn all ES6+ features in detail including let and const, promises, various promise methods, array and object destructuring, arrow functions, async/await, import and export and a whole lot more from scratch?

Check out my Mastering Modern JavaScript book. This book covers all the pre-requisites for learning React and helps you to become better at JavaScript and React.

Check out free preview contents of the book here.

Also, you can check out my free Introduction to React Router course to learn React Router from scratch.

Want to stay up to date with regular content regarding JavaScript, React, Node.js? Follow me on LinkedIn.

Did you find this article valuable?

Support Yogesh Chavan by becoming a sponsor. Any amount is appreciated!