typescriptbeginner
useEventListener Hook
Safely add and clean up DOM event listeners with a type-safe hook supporting window, document, and elements.
typescriptPress ⌘/Ctrl + Shift + C to copy
import { useEffect, useRef } from 'react';
type EventMap = WindowEventMap & DocumentEventMap & HTMLElementEventMap;
function useEventListener<K extends keyof EventMap>(
eventName: K,
handler: (event: EventMap[K]) => void,
element?: HTMLElement | Window | Document | null,
options?: boolean | AddEventListenerOptions,
) {
const savedHandler = useRef(handler);
useEffect(() => {
savedHandler.current = handler;
}, [handler]);
useEffect(() => {
const target = element ?? window;
if (!target?.addEventListener) return;
const listener = (event: Event) => savedHandler.current(event as EventMap[K]);
target.addEventListener(eventName, listener, options);
return () => target.removeEventListener(eventName, listener, options);
}, [eventName, element, options]);
}
// Usage 1: Window events
function WindowResizeDemo() {
useEventListener('resize', () => {
console.log(`Window: ${window.innerWidth}x${window.innerHeight}`);
});
useEventListener('keydown', (e) => {
if (e.key === 'Escape') console.log('Escape pressed');
});
return <div>Resize window or press Escape</div>;
}
// Usage 2: Element events
function ClickOutsideDemo() {
const ref = useRef<HTMLDivElement>(null);
useEventListener('mousedown', (e) => {
if (ref.current && !ref.current.contains(e.target as Node)) {
console.log('Clicked outside!');
}
}, typeof document !== 'undefined' ? document : null);
return (
<div ref={ref} className="bg-[#111] border border-white/10 p-4 rounded-xl">
Click outside this box
</div>
);
}
export { useEventListener };Use Cases
- Window resize handling
- Global keyboard events
- Click outside detection
Tags
Related Snippets
Similar patterns you can reuse in the same workflow.
typescriptbeginner
useClickOutside — Outside Click Detection
Detect clicks outside a referenced element to close dropdowns, modals, and popover menus.
Best for: Dropdown menus
#hooks#click-outside
typescriptbeginner
usePrevious Hook
Track the previous value of any state or prop using a ref-based hook for comparison logic.
Best for: Detecting value changes
#hooks#state
typescriptintermediate
React Custom Hook for Data Fetching
A reusable useFetch hook with loading states, error handling, caching, and abort support.
Best for: Reusable data fetching across components
#react#hooks
typescriptintermediate
React Form Validation Hook
A type-safe form validation hook with field-level errors, dirty tracking, and submit handling.
Best for: Type-safe form handling without libraries
#react#forms