import {createContext, useCallback, useContext, useEffect, useMemo, useRef} from 'react'; interface ContainerListenerContextI { eventFired: () => void; registerListener: (fn: () => void) => void; deregisterListener: (fn: () => void) => void; } const BodyListenerContext = createContext(null); const useBodyListenerContext = () => useContext(BodyListenerContext); export const BodyListenerProvider = BodyListenerContext.Provider; export function useRegisterListener(fn: () => void) { const context = useBodyListenerContext(); return useEffect(() => { if (context) context.registerListener(fn); return () => { if (context) context.deregisterListener(fn); }; }, [fn]); } export function useListener(): ContainerListenerContextI { const listeners = useRef<(() => void)[]>([]); const registerListener = useCallback((fn: () => void) => { listeners.current.push(fn); }, []); const deregisterListener = useCallback((fn: () => void) => { listeners.current = listeners.current.filter((v) => v !== fn); }, []); const eventFired = useCallback(() => { listeners.current.map((fn) => fn()); }, []); return useMemo( () => ({ eventFired, registerListener, deregisterListener }), [] ); }