React SVG 다루기
김영수 주임
들어가며
우리에게 가장 친근한 비트맵 이미지(jpeg, jpg, png)는 사각형의 픽셀이 모여 만들어진 이미지 이기 때문에 확대시 계단현상과 깨짐현상이 나타납니다.
SVG는 벡터 기반으로 각 좌표에 점을 이어서 만들기 때문에 비트맵 이미지와는 다르게 확대를 해도 깨짐현상이 나타나지 않습니다. SVG 이미지는 이미지 그 자체가 아니라 일련의 그리기 명령에 가깝습니다.
사용할 샘플 이미지
- 파일경로: assets/Delete.svg
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M17 6H22V8H20V21C20 ............" fill="black"/>
</svg>
SVG 사용방법
1. img 태그
import DeleteIcon from './Delete.svg'
const SampleComponent = () => {
return (
<div>
<img src={DeleteIcon} />
</div>
)
}
<img>
태그를 사용할 경우 이미지의 width
, height
는 스타일로 수정가능하지만 색은 변경하여 사용 할 수 없습니다.
2. React 컴포넌트로 변환
바꾸고자 하는 svg 요소의 값을 current로 수정합니다.
<svg width="current" height="current" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M17 6H22V8H20V21C20 ............" fill="current"/>
</svg>
current로 바꾼 요소는 사용하는 컴포넌트에서 사용자가 원하는 값을 넣어 커스텀하게 사용할 수 있습니다.
import { ReactComponent as DeleteIcon } from './Delete.svg'
const SampleComponent = () => {
return (
<div>
<DeleteIcon width={200} height={200} fill="#dd9c4f" />
</div>
)
}
3. svgr을 사용하여 React 컴포넌트 생성
yarn add @svgr/cli --dev
# npm 사용할 경우
npm install @svgr/cli --save-dev
터미널에서 변환할 Delete.svg 파일이 위치한 폴더까지 이동후 아래의 커맨드를 입력합니다.
npx @svg/cli --icon Delete.svg
아래와 같이 컴포넌트 소스 코드가 생성됩니다.
import * as React from "react";
function SvgDelete(props) {
return (
<svg
width="1em"
height="1em"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path
d="M17 6h5v2h-2v13a1 1 0 01-1 1H5a1 1 0 01-1-1V8H2V6h5V3a1 1 0 011-1h8a1 1 0 011 1v3zm-8 5v6h2v-6H9zm4 0v6h2v-6h-2zM9 4v2h6V4H9z"
fill="#000"
/>
</svg>
);
}
export default SvgDelete;
컴포넌트 파일 생성 후, 위의 코드를 넣어 사용하면 됩니다.
import DeleteIconComponent from './DeleteIconComponent'
const SampleComponent = () => {
return (
<div>
<DeleteIconComponent width={200} height={200} fill="#dd9c4f" />
</div>
)
}
4. SVG 변환 툴
https://www.svgviewer.dev/
SVG를 React, React Native 컴포넌트로 변환 가능하며 최적화 및 줄바꿈도 처리까지 할 수 있는 웹사이트입니다.
@svgr/cli 라이브러리 설치하여 커맨드로 하기 귀찮으신 분들은 위 사이트를 이용하는 것도 좋은 방법이 될 것 같습니다.