react runtime_error ai_generated true

Warning: useEffect must not return anything besides a function, which is used for clean-up. It looks like you wrote useEffect(async () => ...) or returned a Promise.

ID: react/useeffect-cleanup-return-promise

Also available as: JSON · Markdown · 中文
92%Fix Rate
88%Confidence
1Evidence
2023-06-20First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
React 16.8+ active
React 17.x active
React 18.x active

Root Cause

The cleanup function of useEffect must be either undefined or a synchronous function. Returning a Promise (e.g., from an async function) causes this warning because React cannot call .then() on the cleanup.

generic

中文

useEffect 的清理函数必须是 undefined 或同步函数。返回 Promise(例如来自 async 函数)会导致此警告,因为 React 无法在清理上调用 .then()。

Official Documentation

https://reactjs.org/docs/hooks-effect.html

Workarounds

  1. 95% success Define an async function inside useEffect and call it immediately, then return a cleanup function. Example: useEffect(() => { const fetchData = async () => { /* ... */ }; fetchData(); return () => { /* cleanup */ }; }, []);
    Define an async function inside useEffect and call it immediately, then return a cleanup function. Example: useEffect(() => { const fetchData = async () => { /* ... */ }; fetchData(); return () => { /* cleanup */ }; }, []);
  2. 85% success Use a custom hook like useAsyncEffect from a library (e.g., react-use) that handles async effects properly.
    Use a custom hook like useAsyncEffect from a library (e.g., react-use) that handles async effects properly.
  3. 90% success For simple cases, use .then() and .catch() instead of async/await: useEffect(() => { fetch('/data').then(setData).catch(handleError); return () => { /* cleanup */ }; }, []);
    For simple cases, use .then() and .catch() instead of async/await: useEffect(() => { fetch('/data').then(setData).catch(handleError); return () => { /* cleanup */ }; }, []);

中文步骤

  1. Define an async function inside useEffect and call it immediately, then return a cleanup function. Example: useEffect(() => { const fetchData = async () => { /* ... */ }; fetchData(); return () => { /* cleanup */ }; }, []);
  2. Use a custom hook like useAsyncEffect from a library (e.g., react-use) that handles async effects properly.
  3. For simple cases, use .then() and .catch() instead of async/await: useEffect(() => { fetch('/data').then(setData).catch(handleError); return () => { /* cleanup */ }; }, []);

Dead Ends

Common approaches that don't work:

  1. 90% fail

    The async function still returns a Promise, which React interprets as an invalid cleanup return value.

  2. 85% fail

    Promise.resolve() returns a Promise, still violating the rule that cleanup must be a function or undefined.

  3. 80% fail

    The return value of the async function is a Promise, regardless of wrapping.