
1부에서는 React 프로젝트에서 아이콘을 사용하는 다양한 방법을 다뤘다.
(SVG 인라인 삽입, SVG 파일 import, react-icons 설치 방식 등)
이번 2부에서는 복사한 SVG 아이콘을 실전에서 재사용 가능하게 컴포넌트화하고,
props로 제어 가능한 구조로 관리하는 방법까지 정리한다.
처음엔 <svg>를 그냥 복사해 쓰는 게 편하다.
하지만 아래와 같은 문제가 생긴다.
SVG를 컴포넌트화 + props 기반으로 제어하면 이 문제를 해결할 수 있다.
// 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" />
정렬 방향에 따라 아이콘을 달리 보여주는 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" />
단순히 아이콘만 사용하는 것이 아니라, 보통은 아래와 같은 형태로 쓰이게 된다.
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;
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" />
direction, active, variant 같은 props 분기로 동적 표현이 가능한 아이콘이 필요하다.복사한 SVG를 그대로 쓰지 말고, 명확한 구조와 확장성을 갖춘 컴포넌트로 다뤄보자.