Here is the code in question, which closes a menu when the user clicks outside of it. I need to give proper types everywhere where I inserted "any":
//ANY
const ref = useRef<any>();
useEffect(() => {
//ANY
const checkIfClickedOutside = (event: any) => {
// If the menu is open and the clicked target is not within the menu,
// then close the menu
if (open && ref.current && !ref.current.contains(event.target)) {
setOpen(false);
}
};
document.addEventListener("mousedown", checkIfClickedOutside);
return () => {
// Cleanup the event listener
document.removeEventListener("mousedown", checkIfClickedOutside);
};
}, [open]);
I have implemented ref in a div:
return (
<div className="wrapper" ref={ref}>
<button className="nav-button" onClick={handleOpen}>{menu}</button>
{open && children as React.ReactNode}
</div>
)
The useEffect references this useState hook I created:
//State for Open and Closing Menu
const [open, setOpen] = useState<boolean>(false);
const handleOpen = (event: MouseEvent ) => {
event.preventDefault();
setOpen(!open);
};
Since useRef is implemented in a div, I tried the type HTMLDivElement, like so:
const ref = useRef<HTMLDivElement>();
But the prop in the div complained that:
Types of property 'current' are incompatible.
Type 'HTMLDivElement | undefined' is not assignable to type 'HTMLDivElement | null'.
Type 'undefined' is not assignable to type 'HTMLDivElement | null'.
I then tried changing the type to HTMLDivElement | null, but then it complained about something else, and something else, and so on (this question is already long enough).
I've never implemented useRef before so I'm at a bit of a loss.
Any help is appreciated, thanks!
Seemed to have gotten it working.
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
const checkIfClickedOutside = (event: globalThis.MouseEvent) => {
if (open && ref.current &&
!ref.current?.contains(event?.target as
HTMLDivElement)) {
setOpen(false);
}
};
document.addEventListener("mousedown", checkIfClickedOutside);
return () => {
document.removeEventListener("mousedown", checkIfClickedOutside);
};
}, [open]);