Ever built a modal or dropdown and struggled to figure out how to close it when the user clicks outside it? Yep..
Here's a cool react hook for you that can deal with that
import { useEffect, useRef } from "react";
const useOutsideClickOrScroll = <T extends HTMLElement>(
callback: () => void
) => {
const ref = useRef<T>(null);
useEffect(() => {
const handleClickOutside = (event: MouseEvent) => {
if (ref.current && !ref.current.contains(event.target as Node)) {
callback();
}
};
const handleScroll = () => {
callback();
};
document.addEventListener("mousedown", handleClickOutside);
window.addEventListener("scroll", handleScroll, true);
return () => {
document.removeEventListener("mousedown", handleClickOutside);
window.removeEventListener("scroll", handleScroll, true);
};
}, [callback]);
return ref;
};
export default useOutsideClickOrScroll;
This hook uses useRef
to target a DOM element and triggers a callback on outside clicks or scroll events, ensuring proper cleanup with useEffect. It returns the ref for easy attachment to any DOM element.
Here's a sample usage
import React, { useState } from "react";
import useOutsideClickOrScroll from "./useOutsideClickOrScroll";
const Dropdown = () => {
const [isOpen, setIsOpen] = useState(false);
const handleClose = () => {
setIsOpen(false);
};
const ref = useOutsideClickOrScroll<HTMLDivElement>(handleClose);
return (
<div>
<button onClick={() => setIsOpen(!isOpen)}>Toggle Dropdown</button>
{isOpen && (
<div ref={ref}>
<p>Dropdown Content</p>
</div>
)}
</div>
);
};
export default Dropdown;
Top comments (0)