React 아이콘 사용 완전 정복: 컴포넌트화와 관리

Suyo·2025년 7월 21일
post-thumbnail

1부에서는 React 프로젝트에서 아이콘을 사용하는 다양한 방법을 다뤘다.
(SVG 인라인 삽입, SVG 파일 import, react-icons 설치 방식 등)

이번 2부에서는 복사한 SVG 아이콘을 실전에서 재사용 가능하게 컴포넌트화하고,
props로 제어 가능한 구조로 관리하는 방법까지 정리한다.


1. 왜 아이콘을 컴포넌트로 만들까?

처음엔 <svg>를 그냥 복사해 쓰는 게 편하다.
하지만 아래와 같은 문제가 생긴다.

  • 같은 아이콘이 여러 곳에 중복
  • 크기나 색상 변경 시 일일이 수정
  • 프로젝트가 커질수록 관리 어려움

SVG를 컴포넌트화 + props 기반으로 제어하면 이 문제를 해결할 수 있다.


2. 기본 패턴: SVG를 컴포넌트로 만들기

// components/icons/HomeIcon.jsx
const HomeIcon = ({ size = 20, color = "#000" }) => (
  <svg
    width={size}
    height={size}
    viewBox="0 0 1024 1024"
    fill={color}
    xmlns="http://www.w3.org/2000/svg"
  >
    <path d="M946.5 505L534.6 93.4a31.93 31.93 0 0 0-45.2 0L77.5 505..." />
  </svg>
);

export default HomeIcon;
// 사용 예시
<HomeIcon size={24} color="#333" />

3. 실전 예시: 정렬 아이콘 (asc/desc)

direction props로 상태 제어

정렬 방향에 따라 아이콘을 달리 보여주는 UI라면,
direction이라는 props로 제어하면 깔끔하다.


컴포넌트 예시

// components/icons/SortIcon.jsx
const SortIcon = ({ direction = "asc", size = 20, color = "#000" }) => {
  if (direction === "desc") {
    return (
      <svg
        width={size}
        height={size}
        viewBox="0 0 512 512"
        fill={color}
        xmlns="http://www.w3.org/2000/svg"
      >
        <path d="M304 416h-64a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h64a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM16 160h48v304a16 16 0 0 0 16 16h32a16 16 0 0 0 16-16V160h48c14.21 0 21.38-17.24 11.31-27.31l-80-96a16 16 0 0 0-22.62 0l-80 96C-5.35 142.74 1.77 160 16 160zm416 0H240a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h192a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm-64 128H240a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h128a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM496 32H240a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h256a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z" />
      </svg>
    );
  }

  return (
    <svg
      width={size}
      height={size}
      viewBox="0 0 512 512"
      fill={color}
      xmlns="http://www.w3.org/2000/svg"
    >
      <path d="M304 416h-64a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h64a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm-128-64h-48V48a16 16 0 0 0-16-16H80a16 16 0 0 0-16 16v304H16c-14.19 0-21.37 17.24-11.29 27.31l80 96a16 16 0 0 0 22.62 0l80-96C197.35 369.26 190.22 352 176 352zm256-192H240a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h192a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zm-64 128H240a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h128a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM496 32H240a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h256a16 16 0 0 0 16-16V48a16 16 0 0 0-16-16z" />
    </svg>
  );
};

export default SortIcon;

사용 예시

import SortIcon from "@/components/icons/SortIcon";

<SortIcon direction="asc" />
<SortIcon direction="desc" />

4. 간단한 정렬 버튼 컴포넌트

단순히 아이콘만 사용하는 것이 아니라, 보통은 아래와 같은 형태로 쓰이게 된다.

import { useState } from "react";
import { SortIcon } from "@/components/icons";

const SortButton = () => {
  const [direction, setDirection] = useState("asc");

  const toggleDirection = () => {
    setDirection((prev) => (prev === "asc" ? "desc" : "asc"));
  };

  return (
    <button onClick={toggleDirection}>
      {direction === "asc" ? "오름차순" : "내림차순"}
      <SortIcon direction={direction} />
    </button>
  );
};

export default SortButton;

5. 아이콘 폴더 구조와 통합 관리

src/
└── components/
    └── icons/
        ├── HomeIcon.jsx
        ├── SortIcon.jsx
        └── index.js
// icons/index.js
export { default as HomeIcon } from './HomeIcon';
export { default as SortIcon } from './SortIcon';
// 사용
import { SortIcon } from "@/components/icons";

<SortIcon direction="desc" />

마무리

  • SVG도 결국 하나의 컴포넌트다.
  • 복붙하는 방식에서 벗어나, props로 상태를 제어하고 관리 가능한 구조로 만들어야 유지보수가 편하다.
  • 실무에서는 direction, active, variant 같은 props 분기로 동적 표현이 가능한 아이콘이 필요하다.

복사한 SVG를 그대로 쓰지 말고, 명확한 구조와 확장성을 갖춘 컴포넌트로 다뤄보자.

profile
Mee-

0개의 댓글