• 티스토리 홈
  • 프로필사진
    redpome
  • 방명록
  • 공지사항
  • 태그
  • 블로그 관리
  • 글 작성
redpome
  • 프로필사진
    redpome
    • 분류 전체보기 (50)
      • 내일배움캠프 (23)
      • 웹개발 지식 (2)
      • 프로그래머스 (8)
      • React (7)
      • 코딩테스트 (1)
      • UI-UX (1)
      • 타입스크립트 (2)
      • Next.js (3)
  • 방문자 수
    • 전체:
    • 오늘:
    • 어제:
  • 최근 댓글
      등록된 댓글이 없습니다.
    • 최근 공지
        등록된 공지가 없습니다.
      # Home
      # 공지사항
      #
      # 태그
      # 검색결과
      # 방명록
      • 롤 챔피언 정보 프로젝트 - (2)
        2025년 03월 12일
        • redpome
        • 작성자
        • 2025.03.12.:14

        https://redpome.tistory.com/45

         

        롤 챔피언 정보 프로젝트 - (1)

        Next.js로 롤 정보 페이지를 만드는 프로젝트를 시작했다. 롤에서 API를 가져와 챔피언 목록을 부르던 중에 API 호출 방식에서 다음과 같이 작성했다. export async function getChampions() { const response = await

        redpome.tistory.com

         

        오늘 크게 바뀐 사항은 2가지이다.

         

        • 데이터 페칭을 위한 별도의 함수 생성
        • 아이템 목록 생성

        우선 바뀐 사항에 대해서 정리를 해보자.

         

        import {
          ChampionList,
          ChampionDataInterface,
          ItemDataInterface,
        } from "@/types/apiType";
        import { ChampionDetailInterface } from "@/types/championDetailType";
        import { ItemListInterface } from "@/types/itemType";
        const CHAMPION_API_URL =
          "https://ddragon.leagueoflegends.com/cdn/15.5.1/data/ko_KR/champion.json";
        
        const ITEM_API_URL =
          "https://ddragon.leagueoflegends.com/cdn/15.5.1/data/ko_KR/item.json";
        
        const ONE_DAY_TO_SECONDS = 86400;
        export async function fetchChampionListData(): Promise<ChampionList[]> {
          const response = await fetch(CHAMPION_API_URL, {
            next: { revalidate: ONE_DAY_TO_SECONDS },
          });
        
          if (!response.ok) {
            throw new Error("챔피언 데이터 로드 실패!");
          }
        
          const data: ChampionDataInterface = await response.json();
          return Object.values(data.data);
        }
        
        export async function fetchChampionDetailData(
          id: string
        ): Promise<ChampionDetailInterface> {
          const response = await fetch(CHAMPION_API_URL, { cache: "no-store" });
        
          if (!response) {
            throw new Error("챔피언 상세정보 로드 실패!");
          }
        
          const data = await response.json();
          return data.data[id] as ChampionDetailInterface;
        }
        
        ...

         

        정리하면 ISR 렌더링 방식에 맞게끔 데이터 페이 함수를 만들었다. 어제까지는 그저 1번만 불러와 데이터를 보여주는 상태였기에 ISR 렌더링이라고 볼 수는 없었다.

         

        import { getChampions } from "@/lib/api";
        import ChampionCard from "@/components/ChampionCard";
        import { Champion } from "@/types/apiType";
        export default async function ChampionPage() {
          const championData: Champion[] = await getChampions();
        
          return (
            <div>
              <h2 className="font-bold text-red-500 text-3xl p-4">챔피언 목록</h2>
              <div className="grid grid-cols-4 gap-14 p-6">
                {championData.map((champion) => (
                  <ChampionCard
                    key={champion.id}
                    id={champion.id}
                    name={champion.name}
                    title={champion.title}
                  />
                ))}
              </div>
            </div>


        위의 코드에서는 API에서 데이터를 가져오는 getChampions를 불러오고 갱신을 하는 역할은 없었다.  따라서 데이터 페이 함수를 통해 revalidate를 통한 검증을 하고 지정한 시간에 따라 데이터를 재검증하도록 했다.

         

        import { fetchChampionListData } from "@/utils/serverApi";
        import ChampionCard from "@/components/ChampionCard";
        import { ChampionList } from "@/types/apiType";
        import Link from "next/link";
        
        export default async function ChampionPage() {
          const championData: ChampionList[] = await fetchChampionListData();
        ...

         

        차이점은 fetchChampionListData를 통해 데이터를 가져오는 것이다.

         

        const ONE_DAY_TO_SECONDS = 86400;
        export async function fetchChampionListData(): Promise<ChampionList[]> {
          const response = await fetch(CHAMPION_API_URL, {
            next: { revalidate: ONE_DAY_TO_SECONDS },
          });
        
          if (!response.ok) {
            throw new Error("챔피언 데이터 로드 실패!");
          }
        
          const data: ChampionDataInterface = await response.json();
          return Object.values(data.data);
        }

         

        위와 같이 렌더링 방식에 맞는 데이터 페칭 함수를 설정하였다.


        정리

        데이터 페칭 함수

        • Riot Games에서 제공하는 League of Legends API에서 챔피언 데이터를 불러오기 위해 fetchChampionListData() 함수를 작성했다.
        • next: { revalidate: 86400 } 옵션을 사용하여 24시간(하루) 주기로 데이터를 재검증(ISR)을 하도록 설정했다.

        인터페이스

        • 데이터 타입 관리를 위해 TypeScript로 인터페이스를 정의했다.
        • 그러나 인터페이스의 이름이 확실하지 않은 것 같다, 나 같은 경우 extends를 통해 기존에 만든 인터페이스를 확장하여 필요한 데이터를 추가하는 식으로 썼는데 명확하지 않은 이름이라 중간에 빼먹는 타입 지정 같은 것들도 많았다.

         챔피언 카드 컴포넌트

        • 챔피언의 이름과 타이틀, 이미지 등을 표시할 ChampionCard 컴포넌트를 제작했다.
        • Next.js의 Image 컴포넌트를 활용해 이미지를 최적화했고, URL은 Riot API가 제공하는 id를 이용하여 구성했다.

        ISR 페이지 구성

        • ChampionPage 컴포넌트에서 작성한 페칭 함수를 호출해 데이터를 가져오고, 가져온 데이터를 ChampionCard 컴포넌트에 넘겨 목록을 렌더링했다.
        • Next.js의 Incremental Static Regeneration(ISR)을 활용하여 챔피언 데이터가 24시간마다 재검증되도록 설정했다.

        라우팅 설정

        • 각 챔피언 카드를 클릭하면 상세 페이지로 이동할 수 있도록 <Link>를 설정하고 동적 라우팅 방식을 적용했다.
        • Next.js의 동적 라우팅 방식(/champion/[id])을 통해 챔피언별 상세 페이지 이동이 가능하게 만들었다.

        짤막한 문제점

        • 챔피언의 경우 id 값을 이용해서 이미지를 불렀다. 그러나 아이템 같은 경우에는 id 값이 존재하지 않아 image를 사용했다. 따라서 ${image.full}과 같은 인자로 넘겨주었다.
        • 참고로 챔피언 데이터를 보면 lore와 blurb가 있는데 lore값은 안 읽히는데 blurb 값은 읽힌다. 에러도 뜨지않아서 무엇이 문제인지는 파악하지는 못했다. 어쩌면 더미데이터 일 수도.

         

        '내일배움캠프' 카테고리의 다른 글

        돈워리(Dont Worry) 프로젝트를 마치며  (0) 2025.05.09
        롤 챔피언 정보 프로젝트 - (3)  (0) 2025.03.14
        롤 챔피언 정보 프로젝트 - (1)  (0) 2025.03.11
        아웃소싱 프로젝트 - (2)  (0) 2025.03.05
        아웃소싱 프로젝트 - (1)  (0) 2025.02.27
        다음글
        다음 글이 없습니다.
        이전글
        이전 글이 없습니다.
        댓글
      조회된 결과가 없습니다.
      스킨 업데이트 안내
      현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드 받을 수 있는 페이지로 이동하시겠습니까?
      ("아니오" 를 선택할 시 30일 동안 최신 버전이 감지되어도 모달 창이 표시되지 않습니다.)
      목차
      표시할 목차가 없습니다.
        • 안녕하세요
        • 감사해요
        • 잘있어요

        티스토리툴바