조건부 렌더링을 통해 모달창을 킬 때는 애니메이션 효과를 줄 수 있지만 모달창을 닫는 상황에서 애니메이션 효과를 주기 위해서는 약간의 트릭이 필요하다.
// ModalContainer.js
const [modalState, setModalState] = useState(false);
<Modal
modalState={modalState}
onClose={onClose}
/>
// Modal.js
const Modal = ({ modalState, onClose, children}) => {
if (!modalState) return null;
return (
<div css={modalBackground}>
<div css={modalContainer({ modalState })}>
<a onClick={onClose} css={closeBtn}>
❮
</a>
{children}
</div>
</div>
);
};
export default Modal;
위의 코드 방식으로 modalState 값에 따라 조건부 렌더링이 된다면 modalState값이 false시에 해당 컴포넌트는 렌더링이 되지않아 애니메이션 효과를 줄 수 없다.
이를 해결하기위해서는 자체적으로 state값을 가져 modalState props가 변경했을 때 반응하는 hook을 이용하여 해당 state 값을 변경하는 방식
으로 바꿔주어야한다.
// Modal.js
const Modal = ({ modalState, onClose, children}) => {
const [isOpen, setIsOpen] = useState(false);
useEffect(() => {
let timer;
if (modalState) {
setIsOpen(true);
} else {
timer = setTimeout(() => setIsOpen(false), 500);
}
return () => {
clearTimeout(timer);
};
}, [modalState]);
if (!isOpen) return null;
return (
<div css={modalBackground}>
<div css={modalContainer({ modalState })}>
<a onClick={onClose} css={closeBtn}>
❮
</a>
{children}
</div>
</div>
);
};
export default Modal;
부모로 부터 받은 modalState props를 이용하여 조건부 렌더링을 하는 방식이 아닌 isOpen props를 이용하여 조건부렌더링을 하게된다.
이미 모달창이 켜져있다고 가정했을 때(modalState = true),
닫기 버튼을 눌러 modalState값이 false로 변경되면 modalState props가 변경되었을 때 반응하는 useEffect내부에서 setTimeout함수
를 이용하여 애니메이션이 동작될 수 있도록 잠깐 지연시키는 방식을 이용하면 자연스럽게 모달 창이 닫을 때도 애니메이션을 구현할 수 있다.