Post

Fix useEffect Cleanup Race Condition

Fixed a race condition in useEffect cleanup that could cause memory leaks in certain scenarios.

Fix useEffect Cleanup Race Condition

Problem

A race condition existed where useEffect cleanup functions could be called after a component had already unmounted, leading to potential memory leaks and console warnings in development mode.

Root Cause

The cleanup function wasn’t properly checking if the component was still mounted before executing async operations that were initiated during the effect.

Solution

  • Added internal flag to track mount state
  • Modified cleanup logic to check mount state before executing
  • Updated documentation with best practices
  • Added test cases covering the edge cases

Technical Details

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Before: Race condition possible
useEffect(() => {
  fetchData().then(data => setState(data));
  return () => cleanup();
}, []);

// After: Proper cleanup
useEffect(() => {
  let isMounted = true;
  fetchData().then(data => {
    if (isMounted) setState(data);
  });
  return () => { isMounted = false; cleanup(); };
}, []);

Pull Request

#26853 - Merged on February 5, 2026

This post is licensed under CC BY 4.0 by the author.

Trending Tags