나가기 버튼을 클릭시 모달창 열려야함, 그렇다면 저 화면에서 모달창을 열리고 닫히게 해주면 되겠지!
먼저, 모달을 구성하는 모달 컴포넌트!
<Modal/>
type Props = {
title?: string;
alert?: string;
coin?: number | string;
closeModal?: () => void;
};
const Modal = ({ title, alert, coin, closeModal }: Props) => {
return (
<ModalWrap>
<ModalBackGround onClick={closeModal} />
<ModalContainer>
<Text weight={700} size="2rem">
{title}
</Text>
<ModalAlertText>{alert}</ModalAlertText>
{coin ? (
<ButtonBox>
<Button variant="outlineModalButton">아니오</Button>
<Button variant="outlineCoinModalButton">
<ButtonCoinBox>
<CoinIcon />
{coin}
</ButtonCoinBox>
</Button>
</ButtonBox>
) : (
<ButtonBox>
<Button variant="outlineModalButton">아니오</Button>
<Button variant="modalButton">네</Button>
</ButtonBox>
)}
</ModalContainer>
</ModalWrap>
);
};
export default Modal;
크게 보자면,<ModalWrap/>
,<ModalBackGround/>
, <ModalContainer/>
, 로 구성되어있다.
<ModalWrap/>
const ModalWrap = styled.div`
width: 100vw;
height: 100vh;
`;
전체 모달을 감싸는 컴포넌트로, 화면 크기 전체를 감사주기위해 width, height를 주었다!
<ModalBackGround/>
const ModalBackGround = styled.div`
background-color: rgba(0, 0, 0, 0.6);
width: 100%;
height: 100vh;
position: absolute;
bottom: 0;
left: 0;
`;
모달 컴포넌트를 제외한 뒷부분을 어둡게 만들어주기위한 컴포넌트이다. width, height, position처리!
<ModalContainer/>
const ModalContainer = styled.div`
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border-radius: 2rem;
gap: 2rem;
padding: 3.6rem 0;
border: 1px solid var(--color-white);
background-color: var(--color-white);
position: absolute;
left: 2rem;
top: 30rem;
width: 90%;
`;
실제 모달이 그려지는 컴포넌트이다!
모달을 구성하였다면, 이제 모달을 실제 불러주는 컴포넌트로 들어가서 불러보자!
그전에, 모달을 열어주고 닫아주고 클릭했을때 상태를 변경시켜줘야하는데 이부분을 커스텀훅으로 만들어보았다!
useOpenModal()
import { useState } from "react";
export default function useOpenModal() {
const [isOpenModal, setIsOpenModal] = useState(false);
const clickModal = () => {
setIsOpenModal(true);
};
const closeModal = () => {
setIsOpenModal(false);
};
return { isOpenModal, clickModal, closeModal };
}
왜 ?! 모달을 너무 많이 사용하는데, 공통으로 사용하기위해!
컴포넌트 에서 위에서 만들어준 커스텀훅을 호출해주자!
const { isOpenModal, clickModal, closeModal } = useOpenModal();
{isOpenModal && (
<Modal
closeModal={closeModal}
title="정말로 채팅방을 나가시겠습니까?"
alert="친구신청, 대화에 쓰인 포인트는
환불이 불가능합니다."
/>
)}
처음에 뒷배경을 opacity를 줬는데, 계속 전체 모달의 opacity가 적용되는 문제가 있었다.
이부분을 해결하기위해, 뒷배경을 위한 컴포넌트를 따로 구분하여 해결하였다.
그리고, 모달을 열기위한 행동은 isOpenModal, clickModal, closeModal로 동일한데, 각각 useState로 관리해주어야하는 번거로움이 생겨 useOpenModal이라는 customHook을 만들어 사용하였다.