반응형
> useState 사용
모달 바깥 부분(OutModal)에 투명한 배경을 뷰포트 크기로 깔고 이곳을 클릭했을때 모달을 닫아준다.
여기서 중요한점은
모달(DetailModal)과 모달 바깥 부분(OutModal)은 "형제"여야 하고,
모달의 z-index가 모달 바깥 부분보다 더 높아야한다.
즉 모달과 모달 바깥 부분은 다른 층에 존재하는 것이다. (이벤트 버블링을 막기 위해서!)
// 모달을 사용하는 컴포넌트
function Container() {
const [modal, setModal] = useState(false);
const openModalPopup = () => {
setModal(true);
document.body.style.overflow = "hidden";
};
const closeModalPopup = () => {
setModal(false);
document.body.style.overflow = "";
};
return (
<Button onClick={openModalPopup}>모달 열기</Button>
{modal &&
<ModalComponent close={closeModalPopup} />
})
}
// 모달 컴포넌트
function ModalComponent({ close } : { close: () => void }) {
return (
<ModalWrapper>
<OutModal onClick={close}></OutModal>
<DetailModal>
모달창
</DetailModal>
</ModalWrapper>
)
}
// 모달밖영역과 모달은 형제여야한다.
// 모달밖영역이 모달을 감싼다면 밖이 아니라 모달을 클릭해도 모달이 닫힌다. <이벤트버블링>
const OutModal = styled.div`
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 101;
`;
const DetailModal = styled.section`
// ...
z-index: 102;
`;
> target과 currentTarget 사용
target: 이벤트가 발생한 요소 (클릭한 바로 그것)
currentTarget: 이벤트 리스너(EventListener)를 가진 요소 (이벤트를 실행하는 바로 그것)
모달 전체를 감싸고 있는 ModalWrapper와 모달창 DetailModal으로 예를 들자면,
<ModalWrapper onClick="clickEvent">
<DetailModal>
모달창
</DetailModal>
</ModalWrapper>
모달창 클릭시
- target 👉 DetailModal
- currentTarget 👉 ModalWrapper
모달 바깥 영역 클릭시
- target 👉 ModalWrapper
- currentTarget 👉 ModalWrapper
즉. 모달창 자체를 클릭했을 때 모달 바깥 영역에 있는 이벤트가 발생하지 않도록 하려면?
target과 currentTarget을 일치하는 경우만 이벤트를 발생시키면 된다!!
// 모달을 사용하는 컴포넌트
function Container() {
const [modal, setModal] = useState(false);
const openModalPopup = () => { ... };
const closeModalPopup = () => { ... };
// currentTarget을 지정하기 위한 useRef()
const modalRef = useRef<HTMLDivElement>(null);
const modalOutSideClick = (e: React.MouseEvent) => {
if (modalRef.current === e.target) {
setModal(false);
}
};
return (
{modal &&
<ModalComponent
modalRef={modalRef}
modalOutSideClick={modalOutSideClick}
/>
}
)
}
// 모달 컴포넌트
interface propsType {
modalRef: React.ForwardedRef<HTMLDivElement>;
modalOutSideClick:(e: React.MouseEvent) => void;
}
function useStatementModal({ modalRef, modalOutSideClick }: propsType) {
return (
<ModalWrapper ref={modalRef} onClick={(e) => modalOutSideClick(e)}>
<DetailModal>
모달창
</DetailModal>
</ModalWrapper>
)
}
이벤트 버블링이란?
이벤트 버블링은 이벤트 발생 요소에서부터 순서대로 최상위 부모 요소까지 이벤트가 거품이 터지듯 연달아 발생하는 것!
[참조 URL]
반응형
'React.js' 카테고리의 다른 글
react PDF 다운로드 (2) | 2023.10.11 |
---|---|
구글 애널리틱스 적용하기 2편(react-ga4) (2) | 2023.07.10 |
Axios 호출시, Proxy를 이용하여 크로스브라우징(CORS) 해결하기 (0) | 2023.02.01 |
패키지 업데이트하며 발생한 에러 정리 (0) | 2022.11.30 |
운영서버에 SEO 구현이 안되던 이슈 (react-snap) (0) | 2022.04.08 |
댓글