React에서 svg파일 사용하는 법 (create-react-app)

혜진 조·2022년 3월 20일
19

리액트

목록 보기
3/31
post-thumbnail
post-custom-banner

들어가며

필자는 png, jpeg 등의 파일에 비해 svg파일을 다루기가 까다롭다고 느껴서 이미지 사용 시 svg파일의 사용을 꺼려하곤 했다.
하지만 svg파일은 이미지가 깨지지 않고 용량이 작고 출력이 빠르며 수정과 애니메이션이 가능하다는 장점이 있다.
얼마전 유튜브 클론 코딩 포트폴리오를 준비하면서 정말 많은 Icon 이미지 파일을 불러와야 했다. 그런데 유튜브에서 사용하는 Icon 이미지가 다 svg파일이어서 당황을 하게 되었다. 하지만 선생님의 도움으로 React에서 svg파일을 다루는 법을 알게 되었다. 그 과정이 쉽지 많은 않아서, 이 곳에 기록을 남겨 기억하고 또 다른 사람들과도 공유하려고 한다.

사용방법 소개

✨ 1. svg 파일을 React Component처럼 사용하는 방법

① svg 파일 생성하기

  1. 먼저 svg파일 주소를 복사한다.
  2. src 폴더에 svg 확장자명의 파일(000.svg)을 만들어 추가한다.
    (필자의 경우 편의상 src>assets>images 단계로 폴더를 생성했고, images폴더에 svg파일을 만들어 추가했다.)
  3. 000.svg파일에 복사한 주소를 붙여넣는다.

② svg 파일을 Component로 불러오기

  1. 000.svg파일을 {ReactComponent as 000}의 이름으로 import 해온다.
import { ReactComponent as Hamburger } from "../../../assets/images/Hamburger.svg";
  1. import 해온 파일은 Component 처럼 사용한다. <000 />
const Header = () => {
  return (
        <Icon>
          <Hamburger  /> //이렇게 
        </Icon>
);
};

const Icon = styled.div``
export default Header;
  1. width, height 변경할 때

src에 만든 000.svg파일을 열어 코드를 확인해보면,
widthheight가 설정된 부분이 있는 것을 알 수 있다.
아래 코드처럼 이 부분을 직접 수정하여 사용할 수 있다.

<svg 
viewBox="0 0 24 24"
preserveAspectRatio="xMidYMid meet" 
focusable="false" 
style="pointer-events: none; display: block;
width: 24px; //24px로 수정
height: 24px; //24px로 수정
" 
>
<g>
    <path d="M21,6H3V5h18V6z M21,11H3v1h18V11z M21,17H3v1h18V17z" ></path>
</g>
</svg>

또는 아래 코드처럼 widthheight를 "current"로 변경한 뒤,

<svg 
viewBox="0 0 24 24"
preserveAspectRatio="xMidYMid meet" 
focusable="false" 
style="pointer-events: none; display: block;
width: "current"; //"current"로 수정
height: "current"; //"current"로 수정
" 
>
<g>
    <path d="M21,6H3V5h18V6z M21,11H3v1h18V11z M21,17H3v1h18V17z" ></path>
</g>
</svg>

<000/> svg 컴포넌트에 widthheight를 props로 전달해주는 방법이 있다.

import { ReactComponent as Hamburger } from "../../../assets/images/Hamburger.svg";

const Header = () => {
  return (
        <Icon>
          <Hamburger width="24px" height="24px"/> //이렇게 
        </Icon>
);
};

const Icon = styled.div``
export default Header;

✨ 2. svg 파일을 함수처럼 사용하는 방법

svg를 component처럼 사용하는 방법 외에
우리가 작업하는 component 안에서 svg를 호출하는 함수를 만들어 사용하는 방법도 있다.

함수를 만들어 그 안에 svg 파일 주소를 붙여넣기

필자는 icon이라는 함수를 만들었고, 그 안에 svg 파일 주소를 붙여넣었다.

💡💡이때 svg 파일에 기본적으로 설정된 style부분은 모두 삭제해야 한다! 💡💡

svg파일에 class가 설정되어 있는 경우, jsx에서는 className만 인식하므로 삭제하는 게 좋다.(삭제 안 하면 에러창이 뜬다)


const Header = () => {
  
   const icon = ()=>(
    <svg 
    viewBox="0 0 24 24" 
    preserveAspectRatio="xMidYMid meet" 
    focusable="false" 
    >
    <g><path d="...">
     </path>
     </g>
     </svg> 
 )
  
  
  return (
        <Icon>
    		{icon()}
        </Icon>
);
};

const Icon = styled.div``
export default Header;

✨2-1. svg파일을 여러개 사용해야 하는 경우

만약 우리가 30개의 svg파일을 불러와야 하는 경우를 생각해보자.
그렇게 되면 import를 30번 하거나 함수를 30번 만들어야 하는데, component 코드가 참 난잡해지게될 것이다.
이럴 경우 해당 데이터를 따로 만들어 사용하면 된다.

필자는 src>components>data 단계로 폴더로 생성했고 data폴더에 000.js파일을 만들었다.
그리고 000.js파일에 firstList라는 배열을 만들어 객체형태로 데이터를 정리했다.
이 파일은 우리가 작업하는 component에서 map함수를 돌려 불러올 데이터를 저장해놓는 곳이라고 생각하면 된다.

export const firstList = [
  {
    name: "홈",
    icon: () => (
      <svg
        viewBox="0 0 24 24"
        preserveAspectRatio="xMidYMid meet"
        focusable="false" 
        //style 속성 제거 필수
      >
        <g>
          <path d="M4,10V21h6V15h4v6h6V10L12,3Z"></path>
        </g>
      </svg>
    ),
  },
  {
    name: "탐색",
    icon: () => (
      <svg
        viewBox="0 0 24 24"
        preserveAspectRatio="xMidYMid meet"
        focusable="false"
      >
        <g>
          <path d="..."></path>
        </g>
      </svg>
    ),
  },
  {
    name: "Shorts",
    icon: () => (
      <svg
        viewBox="0 0 24 24"
        preserveAspectRatio="xMidYMid meet"
        focusable="false"
      >
        <g height="24" viewBox="0 0 24 24" width="24">
          <path d="..."></path>
        </g>
      </svg>
    ),
  },
  ... //생략
]

이제 작업하고 있는 component에서 위 데이터 파일을 불러온다

import styled from "styled-components";
import {firstList} from "../../data/youtube/sidebar";

const SideBar = () => {
  return (
      <Container>
        <List>
            {firstList.map(({ name, icon }) => (
            <Item>
              <IconWrapper>{icon()}</IconWrapper> //icon 함수 호출
              <Name>{name}</Name>
            </Item>
          	))}
        </List>
      </Container>
);
};
const Container = styled.div``
const List = styled. div``
const Item = styled. div``
const IconWrapper = styled.div``
const Name = styled.span``

끝. 이제 svg파일을 겁내지 말아야겠다.

profile
나를 믿고 한 걸음 한 걸음 내딛기! 🍏
post-custom-banner

1개의 댓글

comment-user-thumbnail
2023년 1월 8일

완전 좋은 꿀팁 감사합니다!

답글 달기