리액트의 useState를 활용해 모달창을 만들어 보자
두 개의 모달창을 만들고 1번은 외부영역을 클릭하면 모달창이 닫히게
2번은 닫히지 않게 만들어 보자.
in Modal.jsx
// 모달창과 모달 외부영역(overlay) css
const MODAL_STYLE = {
position: "fixed",
top: "50%",
left: "50%",
transform : "translate(-50%, -50%)",
backgroundColor: "#FFF",
padding: "50",
}
const OVERLAY_STYLE ={
position: "fixed"
top: 0,
left: 0,
right: 0,
bottom: 0,
backgroundColor: "rgba(0, 0, 0, 0.6)",
}
in Modal.jsx
const Modal = ({open, onClose, onClickOverlay}) => {
if (!open) return null // 상위 컴포넌트에서 사용할 props들
return (
<div>
<button style={OVERLAY_STYLE} onClick={onClickOverlay} /> // 외부영역
<div style={MODAL_STYLE}> // 모달창 영역
<button>Close modal</button> // 모달 내부 닫기 버튼
</div>
</div>
)
}
export default ModalApp;
in App.jsx
// 자식 컴포넌트와 useState 임포트
const App = () => {
const [isOpen, setIsOpen] = useState(false) // 모달창을 state로 기본값 fasle
return (
<div>
<div>
<button onClick={()=> setOpen(true)}>open modal</button>
<Modal open={isOpen} onClose={()=> setIsopen(false)}
onClilkOverlay={setFirstOpen(false)}></Modal>
</div>
</div>
)
}
open modal 버튼 클릭시 state 값을 true로 만들어 모달창을 띄우고
모달 외부영역을 클릭하면 state 값을 다시 false로 만들어 모달창을 닫아준다.
외부영역 클릭시 닫히지 않는 모달 버튼을 똑같이 하나 더 만들었는데 두 버튼 모두
닫히지 않았다. 콘솔로 확인해봐도 외부영역 클릭시 값이 넘어오지 않고 있었다.
두 번째 모달을 지워보니 다시 잘 작동했다.. 확인을 해보니 하나의 State로
모달창 2개를 관리해서 그런 것이었다. 어쩔 수 없이 state를 하나 더 선언하고
기능 구현을 마치고 이것저것 테스트를 해보았다.
다른 컴포넌트들에 css, z-index 속성이 모달창 보다 높을 경우 모달창이 켜져도
클릭이 가능했다. 내가 원하지 않는 부분이었다.
모달창의 z-index 값을 키우면 당장은 해결이 되겠지만, 뭔가 찝찝했다.
해결 방안을 찾아보던 중 portal을 활용한 모달창 구현 방법을 알아냈다.
리액트 포탈 기능에 대해 알아보고 modal 컴포넌트의 리펙토링을 해봐야겠다!