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.