Bird
Raised Fist0
Reactframework~20 mins

Cleanup function in React - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Cleanup Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ component_behavior
intermediate
2:00remaining
What happens when the cleanup function runs in this React component?

Consider this React component using useEffect with a cleanup function. What will be logged when the component unmounts?

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

function Timer() {
  useEffect(() => {
    const id = setInterval(() => {
      console.log('Tick');
    }, 1000);

    return () => {
      clearInterval(id);
      console.log('Cleanup done');
    };
  }, []);

  return <div>Timer running</div>;
}
ANo logs appear because the cleanup runs immediately.
B"Tick" logs once, and on unmount logs "Cleanup done" multiple times.
C"Tick" logs every second, and on unmount logs "Cleanup done" once.
D"Tick" logs every second, but cleanup never runs on unmount.
Attempts:
2 left
💡 Hint

Think about what useEffect cleanup functions do when the component unmounts.

❓ lifecycle
intermediate
2:00remaining
When does the cleanup function run in this React effect?

Given this React component, when will the cleanup function inside useEffect run?

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

function Counter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log('Effect runs');
    return () => {
      console.log('Cleanup runs');
    };
  }, [count]);

  return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
}
ACleanup runs before the effect runs again and when the component unmounts.
BCleanup never runs because dependencies are present.
CCleanup runs after every render regardless of dependencies.
DCleanup runs only once when the component mounts.
Attempts:
2 left
💡 Hint

Remember how useEffect cleanup works with dependencies.

🔧 Debug
advanced
2:30remaining
Why does this cleanup function cause a memory leak?

Examine this React component. Why does it cause a memory leak despite having a cleanup function?

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

function ScrollTracker() {
  useEffect(() => {
    const onScroll = () => {
      console.log(window.scrollY);
    };
    window.addEventListener('scroll', onScroll);

    return () => {
      // Missing cleanup of event listener
    };
  }, []);

  return <div style={{ height: '200vh' }}>Scroll down</div>;
}
AThe effect runs multiple times causing multiple listeners.
BThe event listener is removed twice causing an error.
CThe cleanup function clears the console logs but not the listener.
DThe cleanup function does not remove the scroll event listener, causing a memory leak.
Attempts:
2 left
💡 Hint

Think about what should happen inside the cleanup function for event listeners.

📝 Syntax
advanced
2:00remaining
Which option correctly defines a cleanup function in useEffect?

Choose the correct syntax for returning a cleanup function inside useEffect in React.

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

function Example() {
  useEffect(() => {
    const timer = setTimeout(() => console.log('Hello'), 1000);

    // Which return is correct?
  }, []);

  return <div>Example</div>;
}
Areturn () => clearTimeout(timer);
Breturn clearTimeout(timer);
Creturn { clearTimeout(timer) };
Dreturn function clearTimeout(timer);
Attempts:
2 left
💡 Hint

The cleanup function must be a function returned from the effect.

❓ state_output
expert
3:00remaining
What is the console output sequence when this component mounts and unmounts?

Analyze this React component. What will be the exact console output sequence when it mounts and then unmounts?

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

function Demo() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log('Effect start', count);
    return () => {
      console.log('Cleanup', count);
    };
  }, [count]);

  useEffect(() => {
    console.log('Mount only');
    return () => {
      console.log('Unmount only');
    };
  }, []);

  return <button onClick={() => setCount(c => c + 1)}>Count: {count}</button>;
}
A"Effect start 0", "Mount only", "Cleanup 0", "Effect start 1", "Cleanup 1", "Effect start 2", "Unmount only"
B"Effect start 0", "Mount only", "Cleanup 0", "Effect start 1", "Cleanup 1", "Effect start 2", "Cleanup 2", "Unmount only"
C"Mount only", "Effect start 0", "Cleanup 0", "Effect start 1", "Cleanup 1", "Effect start 2", "Cleanup 2", "Unmount only"
D"Mount only", "Effect start 0", "Effect start 1", "Effect start 2", "Cleanup 2", "Unmount only"
Attempts:
2 left
💡 Hint

Consider the order of effects and cleanups when dependencies change and when the component unmounts.

Practice

(1/5)
1. What is the main purpose of a cleanup function in a React useEffect hook?
easy
A. To initialize state variables before rendering
B. To remove timers, listeners, or subscriptions when the component unmounts or before the effect reruns
C. To fetch data from an API after the component mounts
D. To render JSX elements conditionally

Solution

  1. Step 1: Understand the role of cleanup functions

    Cleanup functions are used to tidy up side effects like timers or event listeners to prevent memory leaks.
  2. Step 2: Identify when cleanup runs

    Cleanup runs when a component unmounts or before the effect runs again, ensuring resources are freed.
  3. Final Answer:

    To remove timers, listeners, or subscriptions when the component unmounts or before the effect reruns -> Option B
  4. Quick Check:

    Cleanup function purpose = Remove resources [OK]
Hint: Cleanup frees resources when component unmounts or effect reruns [OK]
Common Mistakes:
  • Thinking cleanup initializes state
  • Confusing cleanup with data fetching
  • Assuming cleanup runs after every render
2. Which of the following is the correct syntax to define a cleanup function inside useEffect?
easy
A. useEffect(() => { () => { clearTimeout(timer); }; }, []);
B. useEffect(() => { clearTimeout(timer); return; }, []);
C. useEffect(() => { return () => { clearTimeout(timer); }; }, []);
D. useEffect(() => { return clearTimeout(timer); }, []);

Solution

  1. Step 1: Recognize cleanup function syntax

    The cleanup function must be returned from the effect callback as a function.
  2. Step 2: Check each option

    useEffect(() => { return () => { clearTimeout(timer); }; }, []); correctly returns a function that calls clearTimeout. Others either don't return a function or return the wrong value.
  3. Final Answer:

    useEffect(() => { return () => { clearTimeout(timer); }; }, []); -> Option C
  4. Quick Check:

    Cleanup function = returned function inside useEffect [OK]
Hint: Cleanup must be a returned function inside useEffect [OK]
Common Mistakes:
  • Not returning a function from useEffect
  • Returning the result of cleanup call instead of a function
  • Placing cleanup code outside the returned function
3. What will be logged to the console when the component unmounts in this code?
function Timer() {
  React.useEffect(() => {
    const id = setInterval(() => console.log('tick'), 1000);
    return () => {
      clearInterval(id);
      console.log('cleanup');
    };
  }, []);
  return null;
}
medium
A. Nothing, because the component never unmounts
B. 'tick' once and no 'cleanup'
C. 'cleanup' every second and no 'tick'
D. 'tick' every second and then 'cleanup' once when unmounting

Solution

  1. Step 1: Understand the effect behavior

    The effect sets an interval that logs 'tick' every second and returns a cleanup function that clears the interval and logs 'cleanup'.
  2. Step 2: Trace what happens on unmount

    When the component unmounts, the cleanup runs once, clearing the interval and logging 'cleanup'.
  3. Final Answer:

    'tick' every second and then 'cleanup' once when unmounting -> Option D
  4. Quick Check:

    Interval logs 'tick'; cleanup logs 'cleanup' once [OK]
Hint: Cleanup logs once on unmount, interval logs repeatedly [OK]
Common Mistakes:
  • Thinking cleanup runs repeatedly
  • Confusing interval clearing with immediate stop
  • Expecting no logs at all
4. Identify the error in this React effect with cleanup:
useEffect(() => {
  window.addEventListener('resize', handleResize);
  return window.removeEventListener('resize', handleResize);
}, []);
medium
A. The cleanup function should be a function returned, not the result of removeEventListener call
B. The event listener should be added inside the cleanup function
C. The effect should not have a dependency array
D. handleResize should be defined inside useEffect

Solution

  1. Step 1: Check cleanup function syntax

    The cleanup must be a function returned from useEffect, not the result of calling removeEventListener immediately.
  2. Step 2: Identify correct cleanup pattern

    The cleanup should be: return () => window.removeEventListener('resize', handleResize); to run on unmount.
  3. Final Answer:

    The cleanup function should be a function returned, not the result of removeEventListener call -> Option A
  4. Quick Check:

    Cleanup must be a returned function [OK]
Hint: Return a function for cleanup, not the cleanup call itself [OK]
Common Mistakes:
  • Calling cleanup immediately instead of returning a function
  • Adding event listener inside cleanup
  • Ignoring dependency array effects
5. You want to subscribe to a WebSocket in a React component and clean up properly. Which code correctly uses a cleanup function to close the socket when the component unmounts or the URL changes?
function SocketComponent({ url }) {
  React.useEffect(() => {
    const socket = new WebSocket(url);
    socket.onmessage = (event) => console.log(event.data);
    // What cleanup code is correct?
  }, [url]);
  return null;
}
hard
A. return () => { socket.close(); };
B. socket.close();
C. return socket.close();
D. return () => socket.onmessage = null;

Solution

  1. Step 1: Understand cleanup for WebSocket

    To avoid leaks, the socket must be closed when the component unmounts or URL changes.
  2. Step 2: Identify correct cleanup syntax

    The cleanup must be a function returned from useEffect that calls socket.close(). return () => { socket.close(); }; does this correctly.
  3. Final Answer:

    return () => { socket.close(); }; -> Option A
  4. Quick Check:

    Cleanup returns function closing socket [OK]
Hint: Return a function that closes socket for cleanup [OK]
Common Mistakes:
  • Calling close immediately instead of returning a function
  • Returning the result of close() instead of a function
  • Only nullifying event handlers without closing socket
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard