탭메뉴 컴포넌트 개발하기
💡탭메뉴 컴포넌트란?
탭 메뉴(Tabs) 컴포넌트는 사용자 인터페이스(UI)에서 여러 콘텐츠를 공간 효율적으로 표시하기 위해 사용되는 UI 패턴입니다. 여러 개의 탭을 제공하여 사용자가 클릭하거나 선택할 때마다 다른 콘텐츠를 표시하도록 설계되었습니다. 이는 사용자가 한 화면 내에서 빠르고 직관적으로 다양한 콘텐츠를 탐색할 수 있게 합니다.
- 탭 헤더(Tab Header)
- 각 탭을 나타내는 버튼이나 링크로 구성됩니다.
- 일반적으로 수평으로 정렬되며, 선택된 탭은 활성화 상태(active)를 표시합니다.
- 예를 들어, 현재 선택된 탭에 강조 표시(예: 굵게, 밑줄, 색상 변경)가 추가됩니다.
- 탭 콘텐츠(Tab Content)
- 각 탭에 해당하는 실제 콘텐츠 영역입니다.
- 선택된 탭에 따라 관련 콘텐츠만 표시되며, 나머지는 숨겨집니다.
- 활성 상태 관리(State Management)
- 선택된 탭의 상태를 관리하여 사용자의 입력에 따라 올바른 콘텐츠를 표시합니다.
- 상태 관리 라이브러리(React의 useState 등)를 사용하거나, 전역 상태를 활용할 수도 있습니다.
이 컴포넌트는 주로 다음과 같은 상황에서 사용됩니다.
- 웹 사이트 내비게이션
- 폼 분할
- 데이터 뷰어
❓탭메뉴 컴포넌트를 개발하기 위해 고민할 점
사실 탭메뉴의 구현과 동작은 아코디언컴포넌트와 매우 유사하기 때문에 아코디언 컴포넌트에서 고민했던 점들과 크게 다르지 않습니다. 하지만, 보통 탭 메뉴에서는 아코디언 컴포넌트보다는 더 많고 독립적인 정보를 담는 경우가 많기 때문에 cmd+f 보다는 다른 주제에 더 관심이 있는 것 같습니다.
탭이 활성화되어 있을 때만 렌더 vs 모두 렌더하고 숨기기
모두 렌더하고 css를 이용해서 숨긴다면 탭 전환이 빠르고, 스크롤이 유지될 수 있다는 장점이 있습니다. 저도 이 방법을 알고 나서는 탭을 이런 방식으로 많이 구현했었습니다. 유저입장에서는 성능도 좋아 보이고, 스크롤 위치나 상태를 유지할 수 있다는 장점이 있었으니까요!
하지만, 모든 일에는 장단점이 있는 것 같습니다. 탭이 많고, 각 탭마다 다른 네트웤크요청을 해야 한다면 많은 부하를 줄 수 있습니다. 이 방법으로 프로덕트를 개발했다가, 상대적으로 pod이 적은 next서버에 많은 요청이 한 번에 들어가 서버에 과한 부하를 만들었고 급하게 탭을 수정했던 경험이 있습니다.
그래서, 이 고민의 결론은 개발자가 스스로 잘 판단해야 한다는 것입니다. 탭을 만들 때 내부에 들어가는 상태와 탭 개수 등에 따라 구현한다면 요구사항에 맞춰 개발하는 것은 어렵지 않습니다.
❗️새로 배운 내용
라디오 인풋으로 탭 메뉴 구현해 보기
아코디언 컴포넌트와 마찬가지로 react의 상태를 쓰지 않고 탭 메뉴를 구현할 수 있다는 점이 신기하고 재밌었습니다. 리액트에서 상태를 추가하는 게 사실 성능에 영향을 거의 주지 않는다고 생각하지만, 만약 순수 자바스크립트나 html, css 작업해야 할 경우에는 유용할 수 있을 것 같습니다.
const TabItem = ({
id,
title,
description,
initialChecked,
}: {
id: string
title: string
description: string
initialChecked: boolean
}) => {
return (
<li className={cx('item')} key={id}>
<input
type='radio'
className={cx('input')}
name={'tabmenu'}
id={id}
defaultChecked={initialChecked}
/>
<label className={cx('tab')} htmlFor={id}>
{title}
</label>
<div className={cx('description')}>{description}</div>
</li>
)
}
🎁 결과물