Problem, as an interviewer would state it:
"Attach a debounced resize listener and a throttled scroll listener to window, correctly clean them up, and explain why a naive attach-in-render approach breaks."
Examples:
useEffect(() => {
const onResize = debounce(() => recalcLayout(), 150);
const onScroll = throttle(() => updateScrollProgress(), 100);
window.addEventListener("resize", onResize);
window.addEventListener("scroll", onScroll);
return () => {
window.removeEventListener("resize", onResize);
window.removeEventListener("scroll", onScroll);
onResize.cancel?.();
};
}, []);
Clarifying questions expected:
- Should the debounced/throttled wrapper be created ONCE and reused, or freshly created on every attach?
- Does removeEventListener need the EXACT same function reference used in addEventListener?
- What real cleanup, beyond removeEventListener, is needed on unmount?
Code / implementation expected: Yes — real, direct proof via a real jsdom window that rapid dispatched events produce exactly the expected number of real handler invocations, and that removal genuinely stops further ones.