- Published on
8단계: UI 컴포넌트 예제
8-1. Menu 컴포넌트
상태 기반으로 메뉴를 열고 닫는 기능 구현 예제입니다.
function Menu() {
const [open, setOpen] = useState(false);
return (
<div>
<button onClick={() => setOpen((prev) => !prev)}>메뉴</button>
{open && (
<ul>
<li>홈</li>
<li>게시판</li>
<li>로그아웃</li>
</ul>
)}
</div>
);
}
8-2. Tooltip 컴포넌트
마우스를 올렸을 때 설명을 보여주는 기본 툴팁 구조입니다.
function Tooltip({ message, children }) {
const [hover, setHover] = useState(false);
return (
<span
onMouseEnter={() => setHover(true)}
onMouseLeave={() => setHover(false)}
>
{children}
{hover && <span className="tooltip">{message}</span>}
</span>
);
}
8-3. Timer 컴포넌트
useEffect와 setInterval을 이용해 타이머를 구현합니다.
function Timer() {
const [seconds, setSeconds] = useState(0);
useEffect(() => {
const id = setInterval(() => setSeconds((s) => s + 1), 1000);
return () => clearInterval(id);
}, []);
return <p>경과 시간: {seconds}초</p>;
}
8-4. 상태 초기화와 조건부 렌더링
컴포넌트를 언마운트하거나 초기화할 때 상태가 어떻게 작동하는지 확인합니다.
{show && <Timer />}
<button onClick={() => setShow((prev) => !prev)}>토글</button>
8-5. 외부 스타일 적용 및 재사용
컴포넌트에 클래스 기반 스타일을 적용하거나 styled-components 등도 활용 가능합니다.
function Button({ children }) {
return <button className="btn">{children}</button>;
}
요약
- UI 컴포넌트는 작고 명확한 상태 단위로 나누어 관리
- 이벤트와 상태를 활용해 다양한 동작을 구현할 수 있음
- 공통 인터페이스를 갖도록 props 구성에 신경 써야 함
심화학습
Q1. Tooltip 컴포넌트를 포커스 접근성까지 고려하려면 어떤 점을 개선해야 할까?
A1. onFocus, onBlur 이벤트도 함께 사용하고, aria-label 등의 접근성 속성을 추가해야 한다.
Q2. Timer 컴포넌트에서 setInterval을 cleanup 하지 않으면 어떤 문제가 생기나?
A2. 메모리 누수, 중복 호출 등이 발생할 수 있으며, 컴포넌트가 사라진 후에도 동작이 계속될 수 있다.
Q3. 여러 UI 컴포넌트를 공통 스타일로 관리하려면 어떤 전략이 필요한가?
A3. CSS 모듈, CSS-in-JS(styled-components), 전역 테마 등을 통해 일관된 스타일 시스템을 구축해야 한다.