heisje.devBlog
React.

[React] SVG Sprite 사용법 (StyledComponent)

24. 05. 07.작성자 김희제
React
Figma

사파리에서 아이콘이 작게 나타나는 오류있음. 따라하지 마세요

이슈

SVG를 더 편하게 import하고 싶었다. SVG type을 미리 지정해두고, 자동완성이 되게 만드는 것이 목표였다.

기존의 방법

import arrowRight from "@/shared/icons/arrow_right.svg"
...
 
export const ArrowRightIcon = () =>{
    return <img src={arrowRight} />
}

모든 아이콘에 설정해주기란 너무 귀찮다. sprite로 큰 이미지에서 id로 참조하는 방식으로 보다 쉽게 만들고 싶었다.

해결방법

SVG Sprite를 사용해 SVG를 묶음으로 만든 뒤 id를 참조해서 사용하는 방식으로 해결했다. 아래를 따라오면 해결할 수 있다.

1. 피그마에서 SVG를 Sprite형식으로 가져오기

1-1. 플러그인 설치

SVG를 Sprite형식으로 쉽게 가져올 수 있는 플러그인을 설치하자.

https://www.figma.com/community/plugin/814345141907543603/svg-export

1-2. 아이콘 세팅

피그마에서 아이콘을 만든 뒤 아래 1번이나 2번 처럼 계층구조를 만들어둔다. 둘 다 잘되는 것은 확인했다!

예시 1. 에셋화 안한 아이콘들

react-svgsprite1

예시 2. 에셋화 된 아이콘들

react-svgsprite2

1-3. Sprite로 내보내기

아이콘 그룹을 위의 예시처럼 드래그한 이후 Sprite sheet를 선택 후 Export all을 누른다.

주의: 전체가 group이 되어있으면 안됨, 개별그룹

아래 예시처럼 분리해서 내보내기 해야 id가 잘 들어간다.

react-svgsprite3

1-4. 파일 확인

아래처럼 svg아래에 symbol의 id가 생성되면 성공적으로 추출되었다!

<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
  <defs>
    <symbol id="search" width="24" height="24" fill="none" viewBox="0 0 24 24">
      <path
        fill="#62626D"
        d="m21.85 20.151-4.608-4.607a8.53 8.53 0 0 0 1.736-5.156c0-4.736-3.854-8.589-8.589-8.589C5.653 1.8 1.8 5.653 1.8 10.389c0 4.735 3.853 8.589 8.589 8.589a8.533 8.533 0 0 0 5.156-1.736l4.607 4.607a1.197 1.197 0 0 0 1.697-.001 1.201 1.201 0 0 0 0-1.697ZM4.2 10.389A6.196 6.196 0 0 1 10.39 4.2a6.195 6.195 0 0 1 6.188 6.188 6.195 6.195 0 0 1-6.188 6.188 6.194 6.194 0 0 1-6.19-6.187Z"
      />
    </symbol>
    ...
  </defs>
</svg>

1-5. fill 변경

fill속성이 들어있는 경우 덮어씌우려고 해도, svg에 지정되어있는 색이 우선순위가 된다. 다음처럼 fill="currentColor" 로 바꿔주자.

...
<symbol id="search" width="24" height="24" fill="currentColor" viewBox="0 0 24 24">
  <path fill="currentColor" d="m21.85 20.151-4.608-4.607a8.53 8.53 0 0 0 1.736-5.156c0-4.736-3.854-8.589-8.589-8.589C5.653 1.8 1.8 5.653 1.8 10.389c0 4.735 3.853 8.589 8.589 8.589a8.533 8.533 0 0 0 5.156-1.736l4.607 4.607a1.197 1.197 0 0 0 1.697-.001 1.201 1.201 0 0 0 0-1.697ZM4.2 10.389A6.196 6.196 0 0 1 10.39 4.2a6.195 6.195 0 0 1 6.188 6.188 6.195 6.195 0 0 1-6.188 6.188 6.194 6.194 0 0 1-6.19-6.187Z"/>
</symbol>
...

2. React에서 사용하기

아래는 내가 사용한 SvgIcon 전문이다.

import Svgs from "@/shared/svgs/sprites.svg";
import { HTMLAttributes } from "react";
import styled from "styled-components";
 
export type SVGIconType =
  | "search"
  | "home"
  | "benefit"
  | "pay"
  | "stock"
  | "line_three"
  | "heart"
  | "arrow_right"
  | "rocket"
  | "increase"
  | "pot"
  | "korea"
  | "usa"
  | "graduate"
  | "factory"
  | "vehicle"
  | "meat"
  | "clothes"
  | "cosmetic"
  | "fire"
  | "toss"
  | "default_profile";
 
export interface SVGIconProps extends HTMLAttributes<SVGElement> {
  iconId: SVGIconType;
  size?: string;
  color?: string;
}
 
const Svg = styled.svg`
  position: relative;
`;
 
const Use = styled.use`
  position: absolute;
  bottom: 0;
  right: 0;
`;
 
export const SvgIcon = ({
  iconId,
  size = "100%",
  color,
  ...props
}: SVGIconProps) => (
  <Svg color={color} width={size} height={size} {...props}>
    <Use href={`${Svgs}#${iconId}`} width={size} height={size} />
  </Svg>
);
 

2-1. 주의해서 봐야할 곳 1

svg안에 use라는 계층구조에서 href id값을 참조해서 해결하는 것을 파악할 수 있다.

<svg color={color} width={size} height={size} {...props}>
  <use href={`${Svgs}#${iconId}`} width={size} height={size} />
</svg>

2-1. 주의해서 봐야할 곳 2

id들을 미리 type으로 지정해두고 사용하면 typescript의 자동완성을 사용할 수 있다.

export type SVGIconType =
  | "search"
  | "home"
  | "benefit"
  | "pay"
  | "stock"
  | "line_three"
  | "heart"
  | "arrow_right"
  | "rocket"
  | "increase"
  | "pot"
  | "korea"
  | "usa"
  | "graduate"
  | "factory"
  | "vehicle"
  | "meat"
  | "clothes"
  | "cosmetic"
  | "fire"
  | "toss"
  | "default_profile";
조회수: 0