발생한 오류 🔥
날씨 API를 요청한 후 아이콘 URL을 가져와 `WeatherIcon`컴포넌트를 사용해 여러 개의 날씨 아이콘을 표시하려고 했습니다. 그러나 배열로 `WeatherIcon`을 렌더링 했을 때, 모든 아이콘이 동일한 이미지만 표시되는 현상이 발생했습니다.
해결 과정 🔎
처음에는 각 아이콘의 URL을 제대로 전달하고 있다고 생각했지만, 여러 개의 `WeatherIcon`컴포넌트를 렌더링할 때 브라우저가 첫 번째 요소의 이미지만을 참조하는 것을 깨닫지 못했습니다.
기존 코드
const WeatherIcon = ({ url, className }) => {
const URL = url
? `https://openweathermap.org/img/wn/${url}@2x.png`
: "data:image/png;base64,iVBORw0KG.....";
return (
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
xmlnsXlink="http://www.w3.org/1999/xlink"
className={className}
>
<rect width="24" height="24" fill="url(#pattern0_18_178)" />
<defs>
<pattern
id="pattern0_18_178"
patternContentUnits="objectBoundingBox"
width="1"
height="1"
>
<use xlinkHref="#image0_18_178" transform="scale(0.01)" />
</pattern>
<image id="image0_18_178" width="100" height="100" xlinkHref={URL} />
</defs>
</svg>
);
};
이렇게 작성했을 때 동일한 `id`가 여러 번 사용되어 브라우저가 첫 번째 값만 참조하는 문제가 있었습니다.
해결 방법 ✨
고유한 `id`를 생성해 각 `WeatherIcon`인스턴스에 대한 다른 `id`를 부여하는 방식으로 문제를 해결했습니다.
수정 코드
const uniqueId = Math.random().toString(36).substr(2, 9);
return (
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
>
<rect width="24" height="24" fill={`url(#pattern${uniqueId})`} />
<defs>
<pattern
id={`pattern${uniqueId}`}
patternContentUnits="objectBoundingBox"
width="1"
height="1"
>
<use xlinkHref={`#image${uniqueId}`} transform="scale(0.01)" />
</pattern>
<image id={`image${uniqueId}`} width="100" height="100" xlinkHref={URL} />
</defs>
</svg>
);
각 인스턴스에 고유한 `id`를 부여해 브라우저가 각 아이콘을 올바르게 참조하도록 했습니다.
어려웠던 점 ❓
이 문제를 해결하는데 몇 시간이 걸렸습니다. 초기에는 API에서 가져온 URI이 잘못된 것이라 생각했지만, 결국 SVG 내부의 `id`충돌이 문제라는 것을 깨닫는데 시간이 많이 걸렸습니다.
특히 SVG와 관련된 문제는 일반적인 DOM요소와 다르게 동작하기 때문에 더 혼란스러웠던 것 같습니다.
깨달은 점 ❕
이번 경험을 통해 SVG를 사용할 때 `id`속성이 얼마나 중요한지 깨닫게 되었습니다.
동일한 `id`를 가진 요소가 여러 개 존재할 경우, 브라우저가 첫 번째 요소만 참조하는 점을 명확하게 인지하고 앞으로 SVG를 사용할 때 고유한`id`를 부여해 이런 문제를 예방해야겠다고 생각했습니다.
또한, 복잡한 UI를 구성할 때, 재사용 가능한 컴포넌트를 설계 하는 것이 얼마나 중요한지를 다시 한번 깨닫게 되었습니다.
'공부 > 트러블 슈팅' 카테고리의 다른 글
[트러블 슈팅] issue daily - 로그인 상태 새로고침 시 유지하기 (1) | 2024.10.18 |
---|---|
[트러블 슈팅] supabase에서 Google, Kakao 로그인 시 신규 사용자 저장 오류 (2) | 2024.10.14 |
[트러블 슈팅] Next.js generateStaticParams 정적 경로 생성의 오해와 해결 과정 (0) | 2024.10.07 |
[트러블 슈팅] 카카오맵 API를 활용한 캠핑장 데이터 렌더링 최적화 (0) | 2024.09.19 |
[트러블 슈팅] MBTI 테스트 (Glitch에서 JSON-server의 응답 속도 차이) (1) | 2024.09.11 |
[트러블 슈팅] 방콕 스타일 (새로고침 시 좋아요 랜덤 활성화 이슈) (1) | 2024.09.02 |
[트러블 슈팅] 방콕 스타일 (supabase RLS 오류) (0) | 2024.09.02 |
[트러블 슈팅] 포켓몬 도감 (svg, router, 이벤트 버블링) (0) | 2024.08.26 |