HardAsync in React💻 Output Question

AbortController — cancel fetch on unmount

💡

Hint

This is the correct useEffect cleanup for fetch: return () => controller.abort(). When the component unmounts or deps change, the pending request is cancelled — preventing state updates on unmounted components.

What does this output?

// Simulates useEffect cleanup with AbortController
function makeFetch(signal) {
  return new Promise((resolve, reject) => {
    const timer = setTimeout(() => {
      if (signal.aborted) {
        reject(new Error('AbortError'));
      } else {
        resolve('data loaded');
      }
    }, 10);
    signal.addEventListener('abort', () => {
      clearTimeout(timer);
      reject(new Error('AbortError'));
    });
  });
}

const controller = new AbortController();
let result = null;

makeFetch(controller.signal)
  .then(data => { result = data; })
  .catch(e => { result = 'cancelled: ' + e.message; });

// Component "unmounts" before fetch completes
controller.abort();

setTimeout(() => console.log(result), 20);

Correct Output

cancelled: AbortError

Why this output?

Explanation: abort() fires before the 10ms fetch completes. The abort event listener rejects the promise. .catch captures it as 'cancelled: AbortError'.

Key Insight: This is the correct useEffect cleanup for fetch: return () => controller.abort(). When the component unmounts or deps change, the pending request is cancelled — preventing state updates on unmounted components.

Practice predicting output live →

66 output questions with instant feedback

💻 Try Output Quiz