

위의 버튼을 클릭 시, 모달창을 보이기 위해서 모달창을 키고 끄는 상태를 관리하는 state를 생성했다.
그리고 Modal 컴포넌트에게 해당 state를 전달하여 state값에 따라 렌더링의 변화를 주게끔하였고 모달창을 닫을 수 있는 함수를 전달하는 방식으로 구현하였다.
function DetailImageModalCotainer() {
const [modalState, setModalState] = useState(false);
function onClose() {
setModalState(false);
}
function onOpen() {
setModalState(true);
}
return (
<>
<AllImgBtn onOpen={onOpen} />
<Modal modalState={modalState} onClose={onClose} width={'70vw'} height={'80vh'}>
<div>JSX 태그 안</div>
<div>children prop</div>
</Modal>
</>
);
}
<Modal> JSX 태그 안에 있는 것들은 Modal 컴포넌트의 children prop으로 전달되어 아래와 같은 방식으로 Modal 컴포넌트에서 전달받아 출력할 수 있다.
function Modal({ modalState, onClose, children, width, height }) {
if (!modalState) return null;
return (
<div css={modalBackground}>
<div css={modalContainer({ width, height })}>
<a onClick={onClose} css={closeBtn}>
❮
</a>
{children}
</div>
</div>
);
}

모달 창의 바깥 범위를 클릭 했을 때 modalState 값에 따라 모달창을 닫아주기 위해 eventlistener를 사용하며 알게 된 사실이다.
const [modalState, setModalState] = useState(false);
function handleClick(e) {
console.log(modalState);
}
useEffect(() => {
window.addEventListener('click', handleClick);
return () => {
window.removeEventListener('click', handleClick);
};
}, []);
위의 방식대로 하게 되면 modalState값이 어떤 동작에 의해 true로 변경되었을 때 클릭 이벤트시 호출되는 handleClick함수에서 로그로 찍히는 값은 항상 false이다.
이는 JS에서의 클로저 때문이다.
이를 수정하기 위해서는 아래 코드와 같이 modalState값이 업데이트 되었을 때마다 핸들러를 새롭게 등록시켜줘야 원하는 state 값을 얻을 수 있다.
const [modalState, setModalState] = useState(false);
function handleClick(e) {
console.log(modalState);
}
useEffect(() => {
window.addEventListener('click', handleClick);
return () => {
window.removeEventListener('click', handleClick);
};
}, [modalState]);