오늘은 팀 프로젝트 때 사용할 일이 많은 svg파일들을 가져와서 프로젝트에서 사용할 용도에 맞게 커스텀 가능하도록 컴포넌트로 만드는 작업을 했다. 작업이 꽤나 오래 걸렸지만 그래도 결과물이 나름 괜찮다고 생각했다. 상세한 과정을 전부 기록해서 내 것으로 만들기도 했다.
지난번에 바쁜 주간이 있었는데 바쁘단 이유로 북스터디를 스킵한적이 있었다. 당시 앞으로 바쁘더라도 미리미리 공부를 해서 스터디를 빠지지 않아야겠다고 다짐했는데, 이번주는 팀 프로젝트로 엄청 바쁜 주이지만 틈틈이 공부해서 오늘까지 잘 공부를 이어나가고 있다.
목표: 하나의 svg파일을 가지고 다음과 같이 여러 상태로 사용하기
import { ReactComponent as Star } from “star.svg”;
로 불러와서 사용가능한데, 우리는 vite를 쓰고 있어서 ReactComponent
를 import할 수 없다고 뜬다.
어쩔 수 없이 외부 패키지를 받아 사용해야한다.
npm install @svgr/rollup
이제 정상적으로 ReactComponent as Star
를 사용할 수 있다.
그런데 이렇게 하면 다음과 같이 path가 둘로 나뉘어진 svg파일의 경우, DOM에 렌더링 시 하나의 path로 합쳐진다. 우리는 각 path의 fill값을 다르게 주고 싶은데 하나로 합쳐진다면 그렇게 할 수가 없다. id또한 DOM에 올라갈 때 무시된다.
<svg>
...<path id="path1" ... ></path>
...<path id="path2" ... ></path>
</svg>
이렇게 되면 우리가 특정 path만 색을 입히는 행위를 할 수 없다.
그렇다고 전통적 방식으로 svg를 사용하여 img태그안에 src로 경로를 넣어주면, 아예 커스텀이 불가능해진다. DOM에도 svg태그가 들어가는 것이 아닌 img태그 하나가 들어가기 때문이다.
따라서 그냥 풀 커스텀 하기로 했다. svg파일의 <svg>
, <path>
모두 jsx
에 넣어버리고 직접 하나의 리액트 컴포넌트로 만들어준다.
import React from "react";
import colors from "@/styles/colors";
const OrderFilter = ({ asc, desc }) => {
return (
<svg
width="300"
height="300"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
id="left"
fillRule="evenodd"
clipRule="evenodd"
d="M7.02951 3.44559C7.25372 3.53846 7.3999 3.75724 7.3999 3.99992V12.3999C7.3999 12.7313 7.13127 12.9999 6.7999 12.9999C6.46853 12.9999 6.1999 12.7313 6.1999 12.3999V5.44845L4.42417 7.22418C4.18985 7.4585 3.80995 7.4585 3.57564 7.22418C3.34132 6.98987 3.34132 6.60997 3.57564 6.37566L6.37564 3.57566C6.54724 3.40406 6.80531 3.35272 7.02951 3.44559Z"
fill={asc ? colors.gray7 : colors.gray4}
/>
<path
id="right"
fillRule="evenodd"
clipRule="evenodd"
d="M9.37039 12.9543C9.14619 12.8614 9 12.6427 9 12.4V3.99998C9 3.66861 9.26863 3.39998 9.6 3.39998C9.93137 3.39998 10.2 3.66861 10.2 3.99998V10.9515L11.9757 9.17572C12.2101 8.9414 12.5899 8.9414 12.8243 9.17572C13.0586 9.41003 13.0586 9.78993 12.8243 10.0242L10.0243 12.8242C9.85267 12.9958 9.59459 13.0472 9.37039 12.9543Z"
fill={desc ? colors.gray7 : colors.gray4}
/>
</svg>
);
};
export default OrderFilter;
import React from "react";
import "./App.css";
import OrderFilter from "./components/SVGComponents/OrderFilter";
function App() {
return (
<>
CryptoMeter
<OrderFilter asc />
</>
);
}
export default App;
다음과 같이 잘 동작한다.
자세한 내용은 여기에 정리해두었다.
일급 객체: 다음의 네 가지 조건을 만족하는 객체
런타임에 생성이 가능
변수나 자료구조(객체나 배열)에 할당 가능
매개변수로 사용가능
리턴값으로 사용가능
함수는 객체이지만 일반 객체가 가지지 않는 고유 프로퍼티를 가짐.
팀원이 작성한 컴포넌트 인터페이스를 이해하는데 어려움이 있었다. 솔직히 지금도 이해를 잘 못했다. 다음에 이해하려고 미루어 두고 있는데, 이제 곧 컴포넌트 조립을 시작해야 해서 지금 이해를 해 놔야 한다.