드롭다운을 visible한 element와 드롭다운 컨텐츠를 제외한 곳을 클릭할시에 없어져야한다.
위에 조건때문에 드롭다운을 만드는게 까다롭긴하다 때문에 다음과같이 웹퍼를 만들어 사용하자.
// base
import React, { PropsWithChildren, useEffect, useRef } from 'react';
interface DropDownWrapperProps {
setIsVisible: React.Dispatch<React.SetStateAction<boolean>>;
}
export const DropDownWrapper = ({
setIsVisible,
children,
}: PropsWithChildren<DropDownWrapperProps>) => {
const modalWrapperRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const outSideClick = (e: MouseEvent) => {
// 2. 클릭한위치가 웹퍼 밖인지를 contains으로 확인한다.
if (
modalWrapperRef.current &&
!modalWrapperRef.current.contains(e.target as Node)
) {
setIsVisible(false);
}
};
// 1. 도큐멘트에서 클릭이밴트가 발생할시에
document.addEventListener('click', outSideClick, true);
return () => {
document.removeEventListener('click', outSideClick, true);
};
}, [setIsVisible]);
return <div ref={modalWrapperRef}>{children}</div>;
};
차일드 외에 클릭이 일어날경우 드롭다운을 invisible한다.