구현 목표
- 아래와 같이, 클릭시 아래에서 위로 올라오는 애니메이션과 함께 모달을 구현하고 싶었다.

문제 현상
- 초기에 아래와 같이 코드를 작성하였으나, 애니메이션은 작동하지 않고 컴포넌트만 딱딱하게 렌더링되었다.
스타일 코드
import styled from "styled-components";
const Container = styled.div<{ display: string }>`
display: ${(props) => props.display || "none"};
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
justify-content: center;
align-items: center;
background-color: rgba(0, 0, 0, 0.6);
z-index: 1000; /* 다른 요소들보다 위에 위치하도록 설정 */
`;
const ModalBackground = styled.div`
position: fixed;
left: 0;
top: 0;
right: 0;
bottom: 0;
`;
const ModalWindow = styled.div<{ display: string }>`
display: flex;
flex-direction: column;
align-items: center;
position: fixed;
bottom: 0px;
transform: ${(props) =>
props.display === "flex" ? "translateY(0)" : "translateY(100%)"};
transition: transform 0.3s ease;
border-radius: 10px;
background: ${(props) => props.theme.modalBgColor};
padding: 40px 30px 30px 30px;
z-index: 1001; /* 모달 배경이 컨테이너 뒤에 위치하도록 설정 */
.close {
position: absolute;
right: 10px;
top: -15px;
cursor: pointer;
font-size: 25px;
}
`;
export default { Container, ModalBackground, ModalWindow };
JSX 코드
<Style.Container display={display}>
<Style.ModalBackground onClick={controlFunc} />
<Style.ModalWindow>
<p className="close" onClick={controlFunc}>
×
</p>
{children}
</Style.ModalWindow>
</Style.Container>
원인
- 앞서 작성한 글의 display 속성의 transition 적용 글과 관련이 있다.
해당 글 링크
- 부모 태그인 Container이 렌더 트리 내에 존재하지 않기 때문에, 자식 태그도 마찬가지로 렌더 트리 내에 존재하지 않게 되어 transition 속성이 적용될 수 없는게 원인이였다.
해결
- 따라서 아래와 같이 부모 태그와 자식 태그를 분리하였다.
- 즉, Background 역할을 하는 Container 태그는 display 속성에 따라 조건부 렌더링 하도록 하고(렌더 트리 내 조건부로 존재해도 무방하기 때문에)
- 실질적인 애니메이션이 적용되어야하는 모달 컴포넌트인 ModalWindow 태그는 항상 렌더 트리 내에 존재하도록 하며 transform 속성을 통해 하단에 숨겨놓았다가, 활성화 될 때 위로 올라오도록 하여 구현하였다.
JSX 코드
<>
<Style.Container display={display}>
<Style.ModalBackground onClick={controlFunc} />
</Style.Container>
<Style.ModalWindow display={display}>
<p className="close" onClick={controlFunc}>
×
</p>
{children}
</Style.ModalWindow>
</>