react runtime_error ai_generated true

Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function.

ID: react/setstate-on-unmounted-component-with-async

Also available as: JSON · Markdown · 中文
90%Fix Rate
87%Confidence
1Evidence
2023-09-10First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
React 18.2.0 active
React 19.0.0 active
React 16.14.0 active

Root Cause

An async operation (e.g., fetch, timeout) completes after the component has unmounted, and the callback attempts to set state on the unmounted component.

generic

中文

异步操作(例如 fetch、timeout)在组件卸载后完成,回调尝试在已卸载的组件上设置状态。

Official Documentation

https://react.dev/reference/react/useEffect#cleaning-up-an-effect

Workarounds

  1. 90% success Use an AbortController with fetch and call abort() in the useEffect cleanup: `const controller = new AbortController(); useEffect(() => { fetch(url, { signal: controller.signal }); return () => controller.abort(); }, []);`
    Use an AbortController with fetch and call abort() in the useEffect cleanup: `const controller = new AbortController(); useEffect(() => { fetch(url, { signal: controller.signal }); return () => controller.abort(); }, []);`
  2. 95% success For timeouts, use clearTimeout in cleanup: `useEffect(() => { const timer = setTimeout(() => setState(...), 1000); return () => clearTimeout(timer); }, []);`
    For timeouts, use clearTimeout in cleanup: `useEffect(() => { const timer = setTimeout(() => setState(...), 1000); return () => clearTimeout(timer); }, []);`
  3. 85% success Use a library like `use-http` or `react-query` that handles cancellation automatically.
    Use a library like `use-http` or `react-query` that handles cancellation automatically.

中文步骤

  1. Use an AbortController with fetch and call abort() in the useEffect cleanup: `const controller = new AbortController(); useEffect(() => { fetch(url, { signal: controller.signal }); return () => controller.abort(); }, []);`
  2. For timeouts, use clearTimeout in cleanup: `useEffect(() => { const timer = setTimeout(() => setState(...), 1000); return () => clearTimeout(timer); }, []);`
  3. Use a library like `use-http` or `react-query` that handles cancellation automatically.

Dead Ends

Common approaches that don't work:

  1. 90% fail

    The async task still executes, wasting resources; React recommends cleanup instead.

  2. 95% fail

    It can lead to memory leaks and unpredictable behavior in production, especially with frequent mount/unmount cycles.