지난번 "The-Julge" 프로젝트를 진행하며 svg 파일의 색상을 다루느라 시간을 꽤 쓴 적이 있다. svg 파일 내의 fill 속성에 접근해서 색상값만 변경해 주면 되는 건 알겠는데, 리액트에서 사용하기에 생각보다 번거로웠다. 그러다가 생각해 냈던 방법이 svg 파일을 컴포넌트 화하는 방법이었다. prop으로 색상을 지정해 주는 방법!
그 방법을 생각해내고서 좋은 방법이라고는 생각했는데 굳이 컴포넌트까지 만드는 건 '투 머치'인가 싶은 생각도 들고, 그 방법에 대해 어떤지 물어봤던 팀원의 반응이 뜨뜻미지근해서 결국엔 같은 아이콘을 색상만 바꿔 두 개씩 만들었던 적이 있다. 필요한 색깔이 두 가지였으니 다행이지, 같은 아이콘이 여러 색깔로 필요했다면 파일 하나하나 import 해오기에도, 알맞은 것을 골라 사용하기에도 굉장히 번거로웠을 것이다.
그런데 지난 주에 멘토님께 코드를 보여드리는데, 오히려 svg 파일을 컴포넌트화 하지 않고 사용하고 있는 것에 의아해하셨다. 실무에서는 보통 컴포넌트화해서 사용한다고..(오호)! 그래야 컴포넌트 하나로 재사용성 있게 만들 수 있으니까.
그래서 나도 만들어보았다. 별 건 아니다. 그냥 svg 파일의 내용을 컴포넌트의 리턴값으로 넘겨주면 된다.
👩🏻💻 코드
캘린더를 나타내는 svg 아이콘. 상황에 따라 변경이 필요한 건 색상값이므로 프롭으로 전달받은 색상값이 적용되도록 fill 값을 지정해주었다. || 을 사용하여 기본값을 '#787486'으로 지정. 색상값 외에 적용해야 하는 다른 스타일 속성도 스프레드 문법을 통해 (... styleProps) 프롭으로 전달된다.
export default function CalendarIcon({ fill, ...styleProps }: IconProps) {
return (
<svg
width="18"
height="18"
viewBox="0 0 18 18"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...styleProps}
>
<g id="calendar_today_FILL0_wght300_GRAD0_opsz24 8">
<path
id="Vector"
d="M3.98077 16.1256C3.60193" // 값이 너무 길어서 적당히 자름 ^,^
fill={fill || '#787486'}
/>
</g>
</svg>
);
}
컴포넌트 사용 시에는 단순히 원하는 속성을 전달해 주면 되기 때문에 편리하다.
<CalendarIcon fill="#e3e3e3" className="icon" />
프롭의 타입으로 정의해 준IconProps는 SVGProps를 상속받는데,
이 타입은 또다시SVGAttributes를 상속받는다. 그 안엔 여러 속성의 타입이 옵셔널로 지정되어 있다.
결국 내가 지정해 준IconProps 타입에는 위에 있는 이 모든 속성들의 타입을 상속받고 있기 때문에 fill 타입을 굳이 지정해주지 않더라도 부모로부터 물려받는다. 그렇기 때문에 위의 CalendarIcon 컴포넌트에서 fill 속성을 사용할 수 있었던 것.
export interface IconProps extends SVGProps<SVGSVGElement> {
active?: boolean;
}
내가 임의로 지정해 준 속성은 active 뿐이다. 굳 @~@ (위 코드의 캘린더 아이콘에서는 사용하지 않음)
물론 이 방법에도 장단점이 존재하긴 할 테니 상황에 맞추어 적절한 방법으로 svg 파일을 사용해 보자.
'Frontend > React.js' 카테고리의 다른 글
[React] cloneElement로 변수에 담긴 컴포넌트 활용하기 (1) | 2024.11.28 |
---|---|
[React] 리액트 컴포넌트를 값으로 사용하기 (0) | 2024.11.28 |