UNPKG

@pastable/react

Version:
36 lines (28 loc) 1.09 kB
import { useEffect, useRef } from "react"; import { on } from "@pastable/utils"; import { useIsMountedRef } from "./useIsMounted"; /** Define an event listener on window or a given element declaratively */ export function useEvent<Data = unknown, Event extends keyof HTMLElementEventMap = any>( event: Event, callback: (data: Data) => void, element: HTMLElement | Window = window ) { const callbackRef = useRef<typeof callback>(); const offRef = useRef<Function>(); const isMountedRef = useIsMountedRef(); const safeCallbackRef = useRef(function () { if (!isMountedRef.current) return; callbackRef.current.apply(null, arguments); }); useEffect(() => { const isEqual = callback === callbackRef.current; if (!isEqual) { offRef.current?.(); callbackRef.current = callback; if (callbackRef.current) { offRef.current = on(element, event as any, safeCallbackRef.current); } } return () => offRef.current?.(); }, [callback, element]); }