* 토글 및 다른 항목이 열리면 현재 항목이 닫히는 아코디언 컴포넌트
React 컴포넌트
const Collapse = () => {
const [openIndex, setOpenIndex] = useState<number | null>(null);
// 어떤 항목이 열려 있는지(또는 열려 있지 않으면 null)를 추적하는 상태
const [heights, setHeights] = useState<number[]>([]);
// 각 항목의 높이를 저장하는 상태
const answerRef = useRef<(HTMLDivElement | null)[]>([]);
// 각 항목의 콘텐츠에 대한 참조를 저장하는 ref
// 항목 클릭 시 호출되는 함수
const handleClick = (index : number) => {
setOpenIndex(index === openIndex ? null : index);
// 열기 상태를 토글: 클릭된 항목이 이미 열려 있으면 닫고, 그렇지 않으면 연다.
}
// 각 항목의 높이를 계산하여 저장하는 effect
useEffect(() => {
const AccItemHeight = answerRef.current.map(
(content) => content?.scrollHeight || 0;
);
// 참조를 반복하며 각 콘텐츠 div의 scrollHeight를 가져오거나(참조가 없으면 0을 가져옴)
setHeights(AccItemHeight);
// 계산된 높이로 heights 상태를 업데이트
}, []);
const faqList = [
{},{} // 임시 데이터
];
return (
<>
{faqList.map((item, index) =>(
<div className="item" key={index}>
{/* 항목을 열고/닫는 링크 */}
<Link to="#" onClick={() => handleClick(index)}>
<p>타이틀</p>
</Link>
<div
className="contents"
// 현재 항목에 ref를 할당
ref={(el) => (answerRef.current[index] = el)}
// 항목이 열려 있는지 여부에 따라 maxHeight 설정
style = {{maxHeight : index === openIndex ? `${heights[index]}px` : '0' }}
>
<p>컨텐츠</p>
</div>
</div>
))}
</>
)
}
아코디언 컨텐츠 CSS
.contents {transition : max-height .5s;}
Ant design의 아코디언 컴포넌트 사용 시 1줄로 가능하다.
'JS' 카테고리의 다른 글
CSR과 SSR (4) | 2024.11.14 |
---|---|
머지 리퀘스트(Merge Request) / 풀 리퀘스트(Pull Request) (1) | 2024.07.16 |
JavaScript 객체의 확장, 직렬화, 메서드 (0) | 2024.01.29 |
JavaScript 객체의 프로퍼티 접근 및 조작 방법 (0) | 2024.01.28 |
Try-catch 문 (0) | 2024.01.25 |