0
0
ReactHow-ToBeginner · 3 min read

How to Cleanup in useEffect in React: Simple Guide

In React, you cleanup in useEffect by returning a function from the effect callback. This returned function runs before the component unmounts or before the effect runs again, letting you clear timers, subscriptions, or other resources.
📐

Syntax

The useEffect hook accepts a function that can optionally return a cleanup function. This cleanup function runs when the component unmounts or before the effect runs again if dependencies change.

  • useEffect(() => { ...; return () => { ...cleanup... }; }, [dependencies])
  • The cleanup function is where you undo or clear side effects like timers or event listeners.
  • The dependency array controls when the effect and cleanup run.
javascript
useEffect(() => {
  // setup code here
  return () => {
    // cleanup code here
  };
}, [dependencies]);
💻

Example

This example shows a timer that counts seconds. The cleanup stops the timer when the component unmounts to avoid memory leaks.

javascript
import React, { useState, useEffect } from 'react';

function Timer() {
  const [seconds, setSeconds] = useState(0);

  useEffect(() => {
    const intervalId = setInterval(() => {
      setSeconds(s => s + 1);
    }, 1000);

    return () => {
      clearInterval(intervalId); // cleanup stops the timer
    };
  }, []); // empty array means run once on mount

  return <div>Seconds passed: {seconds}</div>;
}

export default Timer;
Output
Seconds passed: 0 (then increments every second)
⚠️

Common Pitfalls

Common mistakes include forgetting to cleanup, which causes memory leaks or duplicate timers. Another error is not returning a cleanup function or returning it incorrectly.

Also, if dependencies are missing or incorrect, cleanup may not run when expected.

javascript
import React, { useEffect } from 'react';

// Wrong: no cleanup returned
function Wrong() {
  useEffect(() => {
    const id = setInterval(() => console.log('tick'), 1000);
    // no cleanup function returned
  }, []);
  return null;
}

// Right: cleanup returned
function Right() {
  useEffect(() => {
    const id = setInterval(() => console.log('tick'), 1000);
    return () => clearInterval(id);
  }, []);
  return null;
}
📊

Quick Reference

When to CleanupHow to CleanupWhy Cleanup Matters
Before component unmountsReturn a function inside useEffectPrevents memory leaks and bugs
Before effect runs again (if dependencies change)Clear timers, cancel subscriptionsAvoids duplicate side effects
When using event listeners or external resourcesRemove listeners or free resourcesKeeps app performance smooth

Key Takeaways

Always return a cleanup function from useEffect to clear side effects.
Cleanup runs before unmount and before the effect reruns if dependencies change.
Forgetting cleanup can cause memory leaks and unexpected behavior.
Use the dependency array correctly to control when cleanup happens.
Cleanup is essential for timers, subscriptions, and event listeners.