이전 프로젝트에서 SASS로 작업 할때는 아이콘 폰트를 만들어 활용했다.
리액트 프로젝트에서는 아이콘을 어떻게 사용하나 찾아보니 다양한 방법들이 있었다.

  • FontAwesome 웹에서 아이콘이 필요할때 사용하는 라이브러리 (일부 유료)
  • react-icons 리액트 프로젝트에서 빠르게 아이콘을 사용하고 싶을때 활용

하지만 나는 만들어놓은 아이콘 셋이 있기 때문에 svg 활용하는 방법을 찾아봤다.
크기나 색상등을 편하게 수정해서 사용할 수 있도록
svg파일을 컴포넌트화시켜서 활용하는 방법이 제일 좋을 것 같았다.


SVG 파일 추가 및 수정

피그마에서 아이콘 svg파일을 받아 src/assets/svg 경로에 저장했다.
그리고 svg파일 내의 width, height 는 current로, path 태그 내 fill 값은 currentColor로 수정했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<svg
  width="current"
  height="current"
  viewBox="0 0 24 24"
  fill="none"
  xmlns="http://www.w3.org/2000/svg"
>
  <g id="menu">
    <path
      id="Union"
      fill-rule="evenodd"
      clip-rule="evenodd"
      d="M2 6C2 5.44772 2.44772 5 3 5H21C21.5523 5 22 5.44772 22 6C22 6.55228 21.5523 7 21 7H3C2.44772 7 2 6.55228 2 6ZM2 12C2 11.4477 2.44772 11 3 11H21C21.5523 11 22 11.4477 22 12C22 12.5523 21.5523 13 21 13H3C2.44772 13 2 12.5523 2 12ZM3 17C2.44772 17 2 17.4477 2 18C2 18.5523 2.44772 19 3 19H21C21.5523 19 22 18.5523 22 18C22 17.4477 21.5523 17 21 17H3Z"
      fill="currentColor"
    />
  </g>
</svg>


export ReactComponenet

저장한 svg파일을 바로 활용할 곳에서 import해 사용할수도 있지만
여러개의 아이콘을 한번에 export 하기위해 src/assets/svg 경로에 index.ts 파일을 만든다.

1
2
3
4
export { ReactComponent as menu } from "./menu.svg";
export { ReactComponent as close } from "./close.svg";
export { ReactComponent as edit } from "./edit.svg";
// ...


svg 타입 정의

export 하고나면 svg 타입을 지정하라는 타입스크립트 에러가 생긴다.
Cannot find module './menu.svg' or its corresponding type declarations.ts(2307)

같은 경로에 svg.d.ts 파일을 생성해 아래 코드를 추가하고

1
2
3
4
5
6
7
declare module '*.svg' {
  import React = require('react');

  export const ReactComponent: React.FC<React.SVGProps<SVGSVGElement>>;
  const src: string;
  export default src;
}

타입스크립트 컴파일러가 인식할 수 있게 tsconfig.json의 include에 만든 파일 경로를 추가한다.

1
2
3
{
  "include": ["src", "src/components", "src/assets/avg/svg.d.ts"]
}


Icon 컴포넌트 생성

svg의 사이즈나 속성을 쉽게 변경하기 위해 Icon 컴포넌트를 만든다.
src/component 경로에 Icon.tsx 파일 생성 후 각 속성의 타입과 기본값을 정의했다.

svg파일에서 사이즈와 컬러값을 current로 수정해두었기 때문에
props 처럼 원하는 값을 넘겨줄 수 있다.
어떤 종류의 아이콘을 사용할지는 키값으로 받아와 필수 prop으로 사용하도록 만든다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import React, { ReactElement } from 'react';
import * as icons from '../assets/svg';

export type IconType = keyof typeof icons;
export const iconTypes: IconType[] = Object.keys(icons) as IconType[];

export interface IconProps {
  type: IconType;
  color?: string;
  size?: string | number;
}

const NORMAL_SIZE = '24px';
const NORMAL_COLOR = '#3D434B';

function Icon({ type, color, size }: IconProps): ReactElement {
  const SVGIcon = icons[type];
  const fillColor = color || NORMAL_COLOR;
  const widthPx =
    (size &&
      (typeof size === 'number'
        ? `${size}px`
        : `${size.replace('px', '')}px`)) ||
    NORMAL_SIZE;

  return (
    <SVGIcon
      style=
    />
  );
}

export default Icon;


사용할 컴포넌트에서 아이콘 import

아이콘을 사용할 컴포넌트에서 아래와 같이 import해 다른 컴포넌트와 동일한 방식으로 사용할 수 있다.

1
2
3
4
5
6
7
8
9
import Icon from "./Icon";

function App() {
  return (
    <div>
      <Icon type="menu" />
    </div>
  );
}

icon icon 속성이 필수임을 에러로 표시해주고 타입도 추천해준다

컬러와 사이즈는 기본값을 지정해두었기 때문에, 필요한 경우에만 수정하면 된다.


도움받은 글 - React Icon 컴포넌트 만들기

Leave a comment