Categories
React

How to Fix the ‘React Hook Warnings for async function in useEffect: useEffect function must return a cleanup function or nothing’ Error?

Spread the love

The ‘React Hook Warnings for async function in useEffect: useEffect function must return a cleanup function or nothing’ error is something that we may see when we’re writing React apps.

In this article, we’ll take a look at how to fix the ‘React Hook Warnings for async function in useEffect: useEffect function must return a cleanup function or nothing’ error.

Cause of the Error

This error may occur when we try to pass in an async function as an argument of the first argument of the useEffect hook.

The useEffect hook’s first argument cannot be an async function.

If we want to use an async function, then we should define it outside the function and call it.

Or we can define it inside the function and call it.

For instance, instead of writing:

import { useEffect, useState } from "react";

export default function App() {
  const [data, setData] = useState({});

  useEffect(async () => {
    const res = await fetch("https://yesno.wtf/api");
    const data = await res.json();
    setData(data);
  }, []);

  return (
    <div className="App">
      <p>{JSON.stringify(data)}</p>
    </div>
  );
}

We write:

import { useEffect, useState } from "react";

export default function App() {
  const [data, setData] = useState({});

  const getData = async () => {
    const res = await fetch("https://yesno.wtf/api");
    const data = await res.json();
    setData(data);
  };

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

  return (
    <div className="App">
      <p>{JSON.stringify(data)}</p>
    </div>
  );
}

Or we can write:

import { useEffect, useState } from "react";

export default function App() {
  const [data, setData] = useState({});

  useEffect(() => {
    const getData = async () => {
      const res = await fetch("https://yesno.wtf/api");
      const data = await res.json();
      setData(data);
    };
    getData();
  }, []);

  return (
    <div className="App">
      <p>{JSON.stringify(data)}</p>
    </div>
  );
}

We can’t pass an async function into the useEffect as its first argument because it may lead to race conditions.

Async functions complete in an indeterminate amount of time.

And hooks order matter.

Therefore, we can’t use async functions in the useEffect hooka as its argument.

But this doesn’t prevent us from using them.

We can still call then and catch in the useEffect callback.

So we can write:

import { useEffect, useState } from "react";

export default function App() {
  const [data, setData] = useState({});

  useEffect(() => {
    fetch("https://yesno.wtf/api")
      .then((res) => res.json())
      .then((data) => setData(data));
  }, []);

  return (
    <div className="App">
      <p>{JSON.stringify(data)}</p>
    </div>
  );
}

We can have promises in our code, we just can’t write them as async functions if we want to use the function as an argument of useEffect .

Conclusion

To solve the ‘React Hook Warnings for async function in useEffect: useEffect function must return a cleanup function or nothing’ error, we shouldn’t pass async function as the first argument of useEffect .

Instead, we can call promises with functions in different ways.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

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