1. 버튼을 누르면 모달창이 열리고, 모달창 안의 닫기 버튼을 눌러야 닫히는 모달창 만들기
const [isOpen, setIsOpen] = useState(false);
모달의 상태를 boolean값으로 관리할 state를 만들어주고
<button style={onClick={openModal}>
버튼 1
</button>
모달창을 열 버튼 하나를 만들어준디.
const openModal = () => {
setIsOpen(true);
};
그리고 해당 버튼이 눌렀을때 모달을 열어주는 openModal함수를 onClick으로 지정해준다.
openModal 메서드를 통해 버튼이 눌리면 state 값이 false에서 true로 변경된다.
<div onClick={openModal}>
버튼 1
</div>
{
//isOpen이 true일때만 활성화되게
isOpen && (
<div>
<div>
<p>
닫기 버튼을 누르면 닫히는 모달창
</p>
<button onClick={closeModal}> 닫기</button>
<button>확인</button>
</div>
</div>
)
}
모달의 상태를 의미하는 isOpen state 값이 true이면 모달창이 열리는 위 html 코드를 넣어주면 된다.
이제 모달이 화면 한가운데 뜨게 하는 스타일링을 주어야한다.
styled component 패키지를 다운받고 import까지 한 다음
const OuterBox = styled.div` //모달창을 감싸는 젤 바깥쪽 div
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
`;
const InnerBox = styled.div` //모달창을 감싸는 젤 안쪽 div
background-color: #fff;
padding: 20px;
width: 70%;
height: 50%;
border-radius: 12px;
`;
const StBtn = styled.button` //그냥 버튼 스타일링
border: none;
cursor: pointer;
border-radius: 8px;
background-color: rgb(177, 226, 147);
color: rgb(0, 0, 0);
height: 40px;
width: 100px;
margin-right: 10px;
`;
바깥쪽 div의 위치를 뷰포트 기준으로 꽉차게 만들어놓고, flex 속성을 통해서 내부 모달 div가 뷰포트 기준으로 한가운데 정렬하게 만든다.
내부 div는 넓이가 뷰포트의 70%, 높이가 50%인 모달창을 그리게 된다.
return (
<div>
<StBtn onClick={openModal}>
버튼 1
</StBtn>
{
//isOpen이 true일때만 활성화되게
isOpen && (
<OuterBox>
<InnerBox>
<p>
닫기와 확인 버튼 2개가 있고, 외부 영역을 눌러도 모달이 닫히지
않아요
</p>
<StBtn onClick={closeModal}> 닫기</StBtn>
<StBtn>확인</StBtn>
</InnerBox>
</OuterBox>
)
}
</div>
);
적용하면 이렇게 되고,
모달창의 닫기버튼을 누르면 isOpen state가 false로 변경하게 되어 모달창이 닫히게 만드는 함수를 onClick으로 넣어주면 된다.
const closeModal = () => {
setIsOpen(false);
};
2. 버튼을 누르면 모달창이 열리고, 모달창 안의 닫기 버튼이나 모달창 외부영역을 누르면 닫히는 모달창 만들기
우선 모달창 외부의 영역을 useRef를 이용해서 모달창이 열렸을때 모달창 전체의 영역을 ref로 잡아놓는다
const modalRef = useRef();
return (
<div>
<StBtn onClick={openModal}>버튼</StBtn>
{
//isOpen이 true일때만 활성화되게
isOpen && (
<OuterBox ref={modalRef}> //여기!
<InnerBox>
<p>
닫기와 확인 버튼 2개가 있고, 외부 영역을 눌러도 모달이 닫히지
않아요
</p>
<StBtn onClick={closeModal}> 닫기</StBtn>
<StBtn>확인</StBtn>
</InnerBox>
</OuterBox>
)
}
</div>
);
useEffect 훅을 사용하여 렌더링이 됐을때 이벤트 리스너를 더해준다
useEffect(() => {
// 마우스가 해당 영역을 눌렀을때 clickOutside 메서드가 실행되게함
document.addEventListener("mousedown", clickOutside);
return () => {
// 컴포넌트가 없어질때 해당 이벤트를 없애줌
document.removeEventListener("mousedown", clickOutside);
};
}, []);
const clickOutside = (event) => {
if (modalRef.current === event.target) {
closeModal();
}
};
아까 지정한 modalRef의 영역 (모달창 외부의 불투명한 부분)과 클릭한 부분(event.target)이 같다면 closeModal 메서드를 실행시켜 모달창을 닫히게 한다
'TIL' 카테고리의 다른 글
| 7월 4일 TIL - react ) 무한스크롤 구현하기 (Intersection Observer) (0) | 2023.07.04 |
|---|---|
| 6월 29일 TIL react ) 스크롤 올려주는 top 버튼 만들기 (0) | 2023.06.29 |
| 6월 23일 TIL - 리액트) styled component (0) | 2023.06.24 |
| 6월 22일 TIL - redux로 todolist 만들기 (3) - 라우팅 사용해서 todo list 세부페이지 뜨게하기 (0) | 2023.06.22 |
| 6월 21일 TIL - redux로 todolist 만들기 (2) - 추가, 삭제 (0) | 2023.06.22 |