Skip to content

Instantly share code, notes, and snippets.

@aboqasem
Last active October 14, 2021 04:26
Show Gist options
  • Save aboqasem/7a82e9dc065f0714bbf8312a225eadf4 to your computer and use it in GitHub Desktop.
Save aboqasem/7a82e9dc065f0714bbf8312a225eadf4 to your computer and use it in GitHub Desktop.
useEventListener - Event listener hook for React and Next.js
import { useEffect, useRef } from 'react';
type AllEventMaps = HTMLElementEventMap & DocumentEventMap & WindowEventMap;
export function useEventListener<K extends keyof HTMLElementEventMap>(
type: K,
listener: (event: HTMLElementEventMap[K]) => void,
element: HTMLElement,
): void;
export function useEventListener<K extends keyof DocumentEventMap>(
type: K,
listener: (event: DocumentEventMap[K]) => void,
element: Document,
): void;
export function useEventListener<K extends keyof WindowEventMap>(
type: K,
listener: (event: WindowEventMap[K]) => void,
element?: Window,
): void;
export function useEventListener<K extends keyof AllEventMaps>(
type: K,
listener: (event: AllEventMaps[K]) => void,
element?: HTMLElement | Document | Window | null,
) {
const listenerRef = useRef(listener);
useEffect(() => {
listenerRef.current = listener;
});
useEffect(() => {
const el = element === undefined ? window : element;
const internalListener = (ev: AllEventMaps[K]) => {
return listenerRef.current(ev);
};
el?.addEventListener(type, internalListener as EventListenerOrEventListenerObject);
return () => {
el?.removeEventListener(type, internalListener as EventListenerOrEventListenerObject);
};
}, [type, element]);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment