import React, { useRef, useEffect } from "react";
/**
* Hook that alerts clicks outside of the passed ref
*/
function useOutsideAlerter(ref) {
useEffect(() => {
/**
* Alert if clicked on outside of element
*/
function handleClickOutside(event) {
if (ref.current && !ref.current.contains(event.target)) {
alert("You clicked outside of me!");
}
}
// Bind the event listener
document.addEventListener("mousedown", handleClickOutside);
return () => {
// Unbind the event listener on clean up
document.removeEventListener("mousedown", handleClickOutside);
};
}, [ref]);
}
/**
* Component that alerts if you click outside of it
*/
export default function OutsideAlerter(props) {
const wrapperRef = useRef(null);
useOutsideAlerter(wrapperRef);
return <div ref={wrapperRef}>{props.children}</div>;
}
import { useEffect, MutableRefObject } from 'react'
export const useOutsideClick = <T extends Array<MutableRefObject<any>>>(
ref: T,
callback: () => void
): void => {
useEffect(() => {
const handler = (event: MouseEvent): void => {
// Check if the mouse click was within the element's ref.
if (!ref || ref.length === 0) return
const node = ref.find((x) => x?.current?.contains(event?.target as Node))
if (!node) {
callback()
}
}
window.addEventListener('mousedown', handler)
return (): void => {
window.removeEventListener('mousedown', handler)
}
}, [ref, callback])
}
// Usage (it should be in the component*)
const firstRef = useRef(null)
const secondRef = useRef(null)
const handleClick = () => { console.log('Clicked outside ref') }
useOutsideClick([firstRef, secondRef], handleClick)