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), 전역 테마 등을 통해 일관된 스타일 시스템을 구축해야 한다.