← Back to React Course | Chapter 5: Core Hooks | Lesson 3 of 12

useEffect में Cleanup Functions

एक cleanup function useEffect द्वारा अपना अगला काम करने से पहले अपने पीछे साफ़-सफाई करना है, जैसे एक नई recipe शुरू करने से पहले stove बंद करना।
Syntax
markup
useEffect(() => {
  // set up: subscribe, start timer...
  return () => {
    // cleanup: unsubscribe, clear timer...
  };
}, [dependency]);

Returning a Cleanup Function

अगर useEffect को pass किया गया function एक और function return करता है, तो React उस returned function को cleanup logic मानता है। React इसे effect फिर से run करने से ठीक पहले call करता है, और एक आखिरी बार जब component page से हटाया जाता है।

Note: Cleanup functions उन चीज़ों के लिए खासतौर पर important हैं जो background में चलती रहती हैं, जैसे setInterval या एक WebSocket connection।
Warning: एक setInterval effect के लिए cleanup function भूल जाने का मतलब है कि interval component के चले जाने के बाद भी चलता रहता है, resources waste करते हुए।

उदाहरण: Returning a Cleanup Function

markup
<!DOCTYPE html>
<html>
<head>
  <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>
  <script type="text/babel">
    function Timer() {
      const [seconds, setSeconds] = React.useState(0);
      React.useEffect(() => {
        const id = setInterval(() => setSeconds(s => s + 1), 1000);
        return () => clearInterval(id);
      }, []);
      return <p>Seconds: {seconds}</p>;
    }
    ReactDOM.createRoot(document.getElementById('root')).render(<Timer />);
  </script>
</body>
</html>

Cleanup Runs Before Re-running the Effect

जब भी एक effect की dependencies change होती हैं और यह फिर से run होने वाला होता है, React पहले previous cleanup function call करता है। यह ensure करता है कि नए subscriptions या listeners setup होने से पहले पुराने properly हटाए जाएं, duplicates को ढेर होने से रोकते हुए।

Note: Cleanup को हमेशा setup के साथ pair होने वाला सोचें -- अगर effect किसी चीज़ को subscribe करता है, तो cleanup को उसी चीज़ से unsubscribe करना चाहिए।
Warning: बिना cleanup के, एक effect जो हर dependency change पर एक event listener add करता है वह duplicate listeners को ढेर करता रहेगा।

उदाहरण: Cleanup Runs Before Re-running the Effect

markup
<!DOCTYPE html>
<html>
<head>
  <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>
  <script type="text/babel">
    function KeyLogger() {
      const [key, setKey] = React.useState("");
      React.useEffect(() => {
        function handleKey(e) { setKey(e.key); }
        window.addEventListener("keydown", handleKey);
        return () => window.removeEventListener("keydown", handleKey);
      }, []);
      return <p>Last key pressed: {key || "(none yet)"}</p>;
    }
    ReactDOM.createRoot(document.getElementById('root')).render(<KeyLogger />);
  </script>
</body>
</html>

Cleanup on Unmount

जब एक component page से पूरी तरह हटाया जाता है, React इसके effect का cleanup function एक आखिरी बार call करता है। यह उन resources को release करने की standard जगह है जो component उपयोग कर रहा था, ताकि component के चले जाने के बाद कुछ भी चलता न रहे।

Note: अगर आपका component कुछ ऐसा setup करता है जिसे component disappear होने के बाद exist करना बंद कर देना चाहिए, तो वह logic cleanup function में belong करती है।
Warning: एक component जो repeatedly on और off toggle होता है (conditional rendering के through) हर बार mount और unmount होता है, हर बार setup और cleanup भी run करते हुए।

उदाहरण: Cleanup on Unmount

markup
<!DOCTYPE html>
<html>
<head>
  <script src="https://unpkg.com/react@18/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
</head>
<body>
  <div id="root"></div>
  <script type="text/babel">
    function Blinker() {
      React.useEffect(() => {
        console.log("Blinker mounted");
        return () => console.log("Blinker unmounted -- cleanup ran");
      }, []);
      return <p>I blink on and off (see console on toggle).</p>;
    }
    function App() {
      const [show, setShow] = React.useState(true);
      return (
        <div>
          <button onClick={() => setShow(!show)}>Toggle</button>
          {show && <Blinker />}
        </div>
      );
    }
    ReactDOM.createRoot(document.getElementById('root')).render(<App />);
  </script>
</body>
</html>
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. उन effects के लिए cleanup function return करना भूल जाना जो subscriptions, timers, या event listeners setup करते हैं, memory leaks cause करते हुए।
  2. Effect से कोई और चीज़ return करना instead of a function (जैसे एक value या कुछ भी नहीं जब एक function चाहिए था)।
  3. यह assume करना कि cleanup सिर्फ तब run होता है जब component unmount हो -- यह effect के हर re-run से पहले भी run होता है।
चैप्टर सारांश
  • एक cleanup function effect function के अंदर से return होता है।
  • React इसे effect फिर से run होने से पहले, और component unmount होने पर call करता है।
  • Timers, subscriptions, और event listeners के लिए leaks से बचने के लिए cleanup essential है।
  • हर effect को cleanup function की ज़रूरत नहीं होती -- सिर्फ उन्हें जो कुछ ongoing setup करते हैं।
ब्राउज़र सपोर्ट

कोई browser-specific restrictions नहीं -- cleanup behavior Hooks के React 16.8 में introduction से consistent है।

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.