필자는 png, jpeg 등의 파일에 비해 svg파일을 다루기가 까다롭다고 느껴서 이미지 사용 시 svg파일의 사용을 꺼려하곤 했다.
하지만 svg파일은 이미지가 깨지지 않고 용량이 작고 출력이 빠르며 수정과 애니메이션이 가능하다는 장점이 있다.
얼마전 유튜브 클론 코딩 포트폴리오를 준비하면서 정말 많은 Icon 이미지 파일을 불러와야 했다. 그런데 유튜브에서 사용하는 Icon 이미지가 다 svg파일이어서 당황을 하게 되었다. 하지만 선생님의 도움으로 React에서 svg파일을 다루는 법을 알게 되었다. 그 과정이 쉽지 많은 않아서, 이 곳에 기록을 남겨 기억하고 또 다른 사람들과도 공유하려고 한다.
svg
파일 주소를 복사한다. svg
확장자명의 파일(000.svg)을 만들어 추가한다.svg
파일을 만들어 추가했다.)import { ReactComponent as Hamburger } from "../../../assets/images/Hamburger.svg";
const Header = () => {
return (
<Icon>
<Hamburger /> //이렇게
</Icon>
);
};
const Icon = styled.div``
export default Header;
src에 만든 000.svg파일을 열어 코드를 확인해보면,
width
와 height
가 설정된 부분이 있는 것을 알 수 있다.
아래 코드처럼 이 부분을 직접 수정하여 사용할 수 있다.
<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>
또는 아래 코드처럼 width
와 height
를 "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
컴포넌트에 width
와 height
를 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;
svg를 component처럼 사용하는 방법 외에
우리가 작업하는 component 안에서 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;
만약 우리가 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파일을 겁내지 말아야겠다.
완전 좋은 꿀팁 감사합니다!