Monday, June 3, 2024
 Popular · Latest · Hot · Upcoming
152
rated 0 times [  155] [ 3]  / answers: 1 / hits: 36439  / 5 Years ago, wed, february 6, 2019, 12:00:00

I am finding that I am reusing behaviour across an app that when a user clicks outside an element I can hide it.



With the introduction of hooks is this something I could put in a hook and share across components to save me writing the same logic in every component?



I have implemented it once in a component as follows.



const Dropdown = () => {
const [isDropdownVisible, setIsDropdownVisible] = useState(false);
const wrapperRef = useRef<HTMLDivElement>(null);

const handleHideDropdown = (event: KeyboardEvent) => {
if (event.key === 'Escape') {
setIsDropdownVisible(false);
}
};

const handleClickOutside = (event: Event) => {
if (
wrapperRef.current &&
!wrapperRef.current.contains(event.target as Node)
) {
setIsDropdownVisible(false);
}
};

useEffect(() => {
document.addEventListener('keydown', handleHideDropdown, true);
document.addEventListener('click', handleClickOutside, true);
return () => {
document.removeEventListener('keydown', handleHideDropdown, true);
document.removeEventListener('click', handleClickOutside, true);
};
});

return(
<DropdownWrapper ref={wrapperRef}>
<p>Dropdown</p>
</DropdownWrapper>
);
}

More From » reactjs

 Answers
6

This is possible.



You can create a reusable hook called useComponentVisible



import { useState, useEffect, useRef } from 'react';

export default function useComponentVisible(initialIsVisible) {
const [isComponentVisible, setIsComponentVisible] = useState(initialIsVisible);
const ref = useRef<HTMLDivElement>(null);

const handleHideDropdown = (event: KeyboardEvent) => {
if (event.key === 'Escape') {
setIsComponentVisible(false);
}
};

const handleClickOutside = (event: Event) => {
if (ref.current && !ref.current.contains(event.target as Node)) {
setIsComponentVisible(false);
}
};

useEffect(() => {
document.addEventListener('keydown', handleHideDropdown, true);
document.addEventListener('click', handleClickOutside, true);
return () => {
document.removeEventListener('keydown', handleHideDropdown, true);
document.removeEventListener('click', handleClickOutside, true);
};
});

return { ref, isComponentVisible, setIsComponentVisible };
}


Then in the component you wish to add the functionality to do the following:



const DropDown = () => {

const { ref, isComponentVisible } = useComponentVisible(true);

return (
<div ref={ref}>
{isComponentVisible && (<p>Going into Hiding</p>)}
</div>
);

}


Find a codesandbox example here.


[#52645] Friday, February 1, 2019, 5 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
neo

Total Points: 117
Total Questions: 100
Total Answers: 95

Location: Albania
Member since Fri, Jan 28, 2022
2 Years ago
;