개발자
다음과 같이 transition 속성을 적용하여 <Header> 컴포넌트를 클릭했을때, <ContentsWrapper> 컴포넌트가 아코디언 처럼 서서히 펼쳐지고, 접히는 효과를 구현하고 싶습니다. isOpen이 true가 되어 펼쳐지는 효과는 정상적으로 구현되는데, 접히는 효과가 안나타나고 한번에 사라집니다. transition 속성을 어떻게 적용하면 될까요?
1const Container = styled.div`
2 margin-left: 20px;
3`;
4
5const Header = styled.div`
6 width: 250px;
7 height: 30px;
8 margin-top : 20px;
9 margin-bottom: 20px;
10 border-radius: 4px;
11 cursor: pointer;
12`;
13
14const ContentsWrapper = styled.div<{ isOpen: boolean }>`
15 width: inherit;
16 padding: 0 15px 0 15px;
17 overflow: hidden;
18 height: ${({ isOpen }) => (isOpen ? "auto" : "0")};
19 margin-top: ${({ isOpen }) => (isOpen ? "20px" : "0")};
20 max-height: ${({ isOpen }) => (isOpen ? "1000px" : "0")};
21
22 transition: height 1s ease, max-height 1s ease, margin-top 1s ease;
23`;
24
25const Contents = styled.div`
26 padding: 0 15px 0 15px;
27`;
28
29const TestReportOpinion = ({
30 reportAnswerList,
31 positionIndex,
32 question,
33 kind,
34}: {
35 reportAnswerList: reportAnswerList;
36 positionIndex: number;
37 question: string;
38 kind: number;
39}) => {
40
41 const [isOpen, setIsOpen] = useState(true);
42
43 const handleButtonClick = () => {
44 setIsOpen((prev) => !prev);
45 };
46
47return(
48<Container>
49 <Header onClick={handleButtonClick}>
50 <p style={{ width: "400px" }}>
51 {t(question)}
52 <Caretdown style={{ marginLeft: "6px" }} rotate={isOpen ? 0 : 180}/>
53 </p>
54 </Header>
55 <ContentsWrapper isOpen={isOpen}>
56 <Contents>
57 <>
58 <TableRow>
59 <Th width={162} height={44}>
60 {t("등급")}
61 </Th>
62 <Th width={570} height={44}>
63 {t("의견")}
64 </Th>
65 <Th width={125} height={44}>
66 {t("평가")}
67 </Th>
68 </TableRow>
69 ...
70 </>
71 </ContentsWrapper>
72</Container>
73)
답변 1
지금 가입하면 모든 질문의 답변을 볼 수 있어요!
현직자들의 명쾌한 답변을 얻을 수 있어요.
이미 회원이신가요?
커리어리 AI 봇
GPT가 달아주는 답변입니다.
2023년 11월 30일
React에서 트랜지션을 사용하여 아코디언이 접힐 때 서서히 사라지는 효과를 적용하려면, height의 변화와 함께 `opacity`를 사용해볼 수 있습니다. 이 경우 'ContentsWrapper'의 styled-components 정의에 다음과 같이 추가하면 됩니다: ```jsx const ContentsWrapper = styled.div<{ isOpen: boolean }>` ... opacity: ${({ isOpen }) => (isOpen ? "1" : "0")}; transition: height 1s ease, max-height 1s ease, margin-top 1s ease, opacity 1s ease; `; ``` 다만 위 방법은 내용이 많고 wrapper의 높이가 큰 경우, max-height가 즉시 변경되므로 전체 효과가 원하는대로 실행되지 않을 수 있습니다. 높이(height)를 `'auto'`와 `'0px'`로 변경하면서 애니메이션을 작동시키는 것은 어렵습니다(`'auto'`는 이전 특정 값으로부터 점진적으로 변경되는 것을 계산할 수 없기 때문입니다). 따라서 대신에 `maxHeight` 속성을 실제 필요한 최대 높이 값으로 설정하고(1000px 등), 그 값을 기반으로 열림/닫힘 상태를 전환합니다. 아래처럼 코드를 수정해보세요. ```jsx const ContentsWrapper = styled.div<{ isOpen: boolean }>` ... max-height: ${({ isOpen }) => (isOpen ? "1000px" : "0")}; transition: max-height 1s ease-in-out; `; ``` 이렇게 수정하면, 확장 및 축소가 좀 더 자연스럽게 보일 것입니다. 하지만 `max-height` 값은 컨텐츠의 실제 최대 높이보다 항상 크거나 같아야 합니다. 그렇지 않으면 컨텐츠 일부가 잘릴 수 있습니다.
지금 가입하면 모든 질문의 답변을 볼 수 있어요!