기간
2021/11/4 ~ 2021/11/9
메일작성 페이지
<CKEditor />
<Select />
<Datepicker />
Styled Component
Node-schedule
||cron
<Modal />
구현화면
메일작성 페이지에서 전송하기
버튼을 눌렀을때, ConfirmModal 컴포넌트가 화면 중앙에 나타나고, 모달창 바깥 또는 모달창의 닫기
버튼을 눌렀을때, 모달창이 꺼지도록 구현해보려고 한다.
<Buttons />
의 <전송하기> 버튼을 눌렀을때 상태를 변경하기 위해 props로 전달하고, <ConfirmModal />
도 배경과 <닫기> 버튼을 눌렀을때 상태를 변경하기 위해 props로 함수(closeModal)를 전달한다.
따라서 하위 컴포넌트에서 버튼을 클릭했을때 상위 컴포넌트의 상태를 변경할 수 있다.
function Mailform() {
//Buttons에서 <전송하기> 버튼 눌렀을때 상태변경해서 모달창 띄우기
const [isModalOpen, setIsModalOpen] = useState(false);
const closeModal = () => {
setIsModalOpen(!isModalOpen);
};
return (
<>
<div className="Mailform-wrapper">
<Mailinfo />
<Editor />
<Buttons closeModal={closeModal} />
{isModalOpen && <ConfirmModal closeModal={closeModal} />}
</div>
</>
);
}
export default Mailform;
.modal-box
는 position을 absolute로 하고, transform, translate를 사용해 해당 div의 크기로 틀어진 가운데 중심을 맞추어준다.modal-box
는 .confirmModal-container
의 자식요소이므로, 위쪽에 위치시키기 위해 z-index를 사용한다. .confirmModal-container {
width: 100%;
height: 100vh;
border: 1px solid black;
background-color: rgba(0, 0, 0, 0.4);
z-index: 10;
position: fixed;
top: 0;
left: 0;
}
.confirmModal-container .modal-box {
width: 300px;
height: 200px;
background-color: white;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
z-index: 100;
}
이 부분은 이해하기 어려운 부분 중 하나였다. z-index를 사용했기 때문에, 모달창을 눌렀을때에는 모달창이 닫히면 안된다고 생각했다. 다시말해, 회색 배경 또는 모달창의 취소버튼을 눌렀을때만 모달창이 닫히도록 하고 싶었고, 모달창은 눌러도 닫히면 안됐다. 그런데, 모달창을 눌렀을때도 창이 닫혔다.
원인은 z-index는 같은 레벨의 요소들 간에만 적용된다는 점에 있었다.자식요소에 z-index를 준다고 해도 부모 요소 위에 있는 것이 아니라는 뜻이다. 자식요소의 z-index를 아무리 높여도 부모 밖으로는 나갈 수 없다. 부모요소 안에 있는 자식요소 부분을 클릭하더라도 모달창이 닫힌 것이다.
event.target과 event.currentTarget을 활용해 문제를 해결할 수 있었다. 회색배경을 클릭했을때는 handleclose 함수를 동작시켜 e.target === e.currentTarget
인 경우에만 closeModal 함수를 동작시킨다. 그리고, 취소 버튼을 클릭했을때에는 바로 closeModal 함수를 동작시킨다.
다음을 보면, 차례로 두개씩 모달창을 눌렀을때, 회색배경을 눌렀을때, 취소버튼을 눌렀을때 e.target
과 e.currentTarget
이다.
즉, 모달창을 눌렀을때에는 e.target은 모달창이지만 e.currentTarget은 회색박스로 일치하지 않으므로 모달창이 닫히지 않고, 회색배경을 눌렀을때는 이 두개가 일치하므로 모달창이 닫힌다. (css에 적용했던 z-index는 지워도 된다.)
function ConfirmModal({ closeModal }) {
const handleClose = (e) => {
console.log(e.target);
console.log(e.currentTarget);
if (e.target === e.currentTarget) {
closeModal();
}
};
return (
<>
<div className="confirmModal-container" onClick={handleClose}>
<div className="modal-box">
<p>
예약이 완료된 편지는 전송취소가 불가합니다. 편지를 보내시겠습니까?
</p>
<button className="btn-close" onClick={closeModal}>
취소
</button>
<button className="btn-close" onClick={}>
보내기
</button>
</div>
</div>
</>
);
}