스파르타코딩클럽/과제

[Next.js/Typescript] LOL_Dex: 컴포넌트에서 버전 정보 전달하기

myinfo7091 2024. 12. 19. 04:45

구현 목표

리그 오브 레전드 아이템 정보 페이지에 사용될 아이템 카드 컴포넌트를 만들고 알맞은 이미지를 가져와서 사용한다.

 

 

문제점: 컴포넌트에서 버전 정보 전달 오류

각종 이미지와 기본 URL 사용을 위해 constants.ts에 필요한 URL과 생성 함수를 정리했는데, ItemCards 컴포넌트에서 각 아이템에 해당하는 이미지가 로드되지 않았다. 확인한 내용은 아이템 이미지를 가져오기 위해 URL을 생성하는 getItemImgUrl 함수가 버전 정보를 필요로 한다는 것이다.

// constants.ts 예시

// Data Dragon API 기본 URL
export const API_URL = "https://ddragon.leagueoflegends.com";

// 챔피언 스퀘어 이미지 URL
export const SQUARE_IMG_URL = `${API_URL}/cdn/14.24.1/img/champion`;

// 챔피언 스플래시 아트 이미지 URL
export const SPLASH_IMG_URL = `${API_URL}/cdn/img/champion/splash`;

// 최신 버전 데이터 URL
export const getDataUrl = (version: string) =>
  `${API_URL}/cdn/${version}/data/ko_KR`;

.
.
.

 

 

원인 파악: version이 undefined가 되어 getItemImgUrl 함수에 잘못된 값 전달

아니나 다를까 version 값이 제대로 전달되지 않은 채 ItemCards 컴포넌트가 렌더링되고 있었다. undefined인 상태로 ItemCard 컴포넌트에 버전 정보가 전해지면서 잘못된 URL이 생성되어 이미지가 로드되지 않았음을 확인했다.

 

코드 수정을 위해 fetchVersion()을 사용해서 페이지 컴포넌트(items/page.tsx)에서 버전 정보를 미리 가져오고, ItemCards 컴포넌트에 props로 전달했다.

 

 

수정한 코드

  • getItemImgUrl 함수
    버전과 아이템 이미지를 인자로 받아서 URL을 반환한다.
export const getItemImgUrl = (version: string, itemImg: string) =>
  `https://ddragon.leagueoflegends.com/cdn/${version}/img/item/${itemImg}`;

 

  • ItemCards 컴포넌트
    props로 전달받은 버전과 아이템 정보를 바탕으로 이미지 URL을 생성한다. 
import React from "react";
import { Item } from "@/types/Item";
import Image from "next/image";
import { getItemImgUrl } from "@/constants/constants";

interface ItemCardProps {
  item: Item;
  version: string;
}

const ItemCards = ({ item, version }: ItemCardProps) => {
  const IMG_URL = getItemImgUrl(version, item.image.full);

  return (
    <div className="flex flex-col items-center p-4 bg-white dark:bg-gray-800 rounded-lg shadow-md text-center">
      <Image
        src={IMG_URL}
        alt={item.name}
        width={80}
        height={80}
        className="rounded-md"
      />
      <p className="mt-3 text-sm font-medium text-gray-800 dark:text-gray-300 truncate">
        {item.name}
      </p>
    </div>
  );
};

export default ItemCards;

 

  • ItemPage 컴포넌트
    version 값을 가져오고 ItemCards 컴포넌트에 전달해준다.
import React from "react";
import ItemCards from "@/components/ItemCards";
import { fetchItems, fetchVersion } from "@/utils/serverApi";
import { Item } from "@/types/Item";

export default async function ItemsPage() {
  // 버전 정보 가져오기
  const version: string = await fetchVersion();
  const items: Item[] = await fetchItems();

  return (
    <div className="min-h-screen flex flex-col items-center py-8 bg-gray-100 dark:bg-gray-900">
      <h1 className="text-3xl font-bold mb-6 text-gray-800 dark:text-white">
        아이템 목록
      </h1>
      <div className="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-6">
        {items.map((item) => (
          <ItemCards key={item.id} item={item} version={version} />
        ))}
      </div>
    </div>
  );
}

 

 

요약

  • 발생한 문제
    version 값이 undefined로 전달되어 이미지 URL 생성 실패
  • 해결 방법
    페이지 컴포넌트에서 fetchVersion()을 호출해 버전 정보를 정상적으로 가져오고, props로 ItemCards에 전달
  • 결과
    버전 정보가 잘 전달되고, getItemImgUrl 함수도 알맞은 이미지 URL을 생성해서 표시해줄 수 있다

props 전달 잘 해줘야겠지?