Categories
React

How to Fix the React ‘useEffect function must return a cleanup function or nothing’ Warning Message?

Spread the love

If we have async functions in our useEffect hook, we may get the ‘useEffect function must return a cleanup function or nothing’ warning in our console.

In this article, we’ll look at how to fix this warning.

Moving Async Functions Outside the useEffect Hook

To fix this warning, we shouldn’t use async functions as the callback in the first argument.

useEffect expects a synchronous function in the first argument.

Therefore, instead of writing:

import React, { useEffect, useState } from "react";

export default function App() {
  const [posts, setPosts] = useState({});

  useEffect(async () => {
    try {
      const response = await fetch(`https://www.reddit.com/r/react.json`);
      const json = await response.json();
      setPosts(json.data.children.map((it) => it.data));
    } catch (e) {
      console.error(e);
    }
  }, []);

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

We write:

import React, { useEffect, useState } from "react";

export default function App() {
  const [posts, setPosts] = useState({});

const getPosts = async () => {
    try {
      const response = await fetch(`https://www.reddit.com/r/react.json`);
      const json = await response.json();
      setPosts(json.data.children.map((it) => it.data));
    } catch (e) {
      console.error(e);
    }
  };

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

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

Instead of using the async function as the callback of the useEffect hook, we create a new getPosts function with our promise code.

We can also have async functions defined inside the useEffect callback.

So we can also write:

import React, { useEffect, useState } from "react";

export default function App() {
  const [posts, setPosts] = useState({});

  useEffect(() => {
    const getPosts = async () => {
      try {
        const response = await fetch(`https://www.reddit.com/r/react.json`);
        const json = await response.json();
        setPosts(json.data.children.map((it) => it.data));
      } catch (e) {
        console.error(e);
      }
    };

    getPosts();
  }, []);

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

If we use the function only once, we can keep it inside the useEffect callback.

Conclusion

We can fix the ‘useEffect function must return a cleanup function or nothing’ easily by defining an async function separately and using it instead of passing in an async function as a callback of the useEffect hook.

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 *