til

Next.js입문 5일 차 @개인 과제 55%

fpzmfks 2024. 10. 1. 21:16

오늘은 개인과제에 집중해서 과제를 반 정도 해내었다. 3개의 데이터 목록을 완성하고, 1개의 상세페이지를 불러올 수 있게 되었으므로 이로써 3.5/6를 완성한 것이다. 앞으로 2개의 상세페이지 데이터를 불러오고 상세페이지 css를 가다듬으면 과제가 일단락된다. (또 저번에 겪었던 route handler 문제client컴포넌트에서 사용하니까 정상적으로 작동했다. 역시 server컴포넌트에서는 route handler를 사용하면 안 되는 것이었던 모양이다.)

 

이번 과제는 get 요청으로 페이지를 구성하는 단순한 것이라서 과제 진척 자체는 빨랐다. 만약 javascript로 만드는 것이었으면 오늘 하루만에 끝낼 수도 있었을 것 같다. 다만 typescript환경에서 api 통신으로 데이터를 받아와서 활용하는 것은 생각보다 어려운 일이었다. 

 

가장 난감했던 것이 데이터 목록 내의 각 데이터들의 형식들이 조금씩 달랐던 것이었는데, 일단 해보니까 되는 걸 보면 어쩌면 별 문제 아닌 것 같기도 하다. 다만 한 가지 주의할 점은 실제로 모든 데이터를 정상적으로 불러왔더라도 해당 데이터를 정의한 type에 일부 데이터 형식이 누락되어 있다면, 내가 type에서 누락된 데이터를 사용할 수 없다는 것이다. 

 

아래 두 개의 좀 쓸데없이 긴 두 타입은 각각 champion과 championDetail의 응답 데이터의 타입을 정의한 것으로 두 응답 데이터는 비슷해보이지만 형식이 조금 달라서 이 둘 중 하나의 타입만을 사용해서 유사한 2개의 api요청을 정의한다면 일부 데이터를 사용할 수 없게 된다

export type Champion = {
  version: string;
  id: string;
  key: string;
  name: string;
  title: string;
  blurb: string;
  info: {
    attack: number;
    defense: number;
    magic: number;
    difficulty: number;
  };
  image: {
    full: string;
    sprite: string;
    group: string;
    x: number;
    y: number;
    w: number;
    h: number;
  };
  tags: [string];
  partype: string;
  stats: {
    hp: number;
    hpperlevel: number;
    mp: number;
    mpperlevel: number;
    movespeed: number;
    armor: number;
    armorperlevel: number;
    spellblock: number;
    spellblockperlevel: number;
    attackrange: number;
    hpregen: number;
    hpregenperlevel: number;
    mpregen: number;
    mpregenperlevel: number;
    crit: number;
    critperlevel: number;
    attackdamage: number;
    attackdamageperlevel: number;
    attackspeedperlevel: number;
    attackspeed: number;
  };
};
export type ChampionDetailData = {
  id: {
    id: string;
    key: string;
    name: string;
    title: string;
    image: {
      full: string;
      sprite: "champion0.png";
      group: string;
      x: number;
      y: number;
      w: number;
      h: number;
    };
    skins: { id: string; num: number; name: string; chromas: boolean }[];
    lore: string;
    blurb: string;
    allytips: string[];
    enemytips: string[];
    tags: string[];
    partype: string;
    info: {
      attack: number;
      defense: number;
      magic: number;
      difficulty: number;
    };
    stats: {
      hp: number;
      hpperlevel: number;
      mp: number;
      mpperlevel: number;
      movespeed: number;
      armor: number;
      armorperlevel: number;
      spellblock: number;
      spellblockperlevel: number;
      attackrange: number;
      hpregen: number;
      hpregenperlevel: number;
      mpregen: number;
      mpregenperlevel: number;
      crit: number;
      critperlevel: number;
      attackdamage: number;
      attackdamageperlevel: number;
      attackspeedperlevel: number;
      attackspeed: number;
    };
    spells: {
      id: string;
      name: string;
      description: string;
      tooltip: string;
      leveltip: {
        label: string[];
        effect: string[];
      };
      maxrank: number;
      cooldown: number[];
      cooldownBurn: string;
      cost: number[];
      costBurn: string;
      // datavalues:null
      effect: (number[] | null)[];
      effectBurn: (string | null)[];
      vars: [];
      costType: string;
      maxammo: string;
      range: number[];
      image: {
        full: string;
        sprite: string;
        group: string;
        x: number;
        y: number;
        w: number;
        h: number;
      };
    }[];
    passive: {
      name: string;
      description: string;
      image: {
        full: string;
        sprite: string;
        group: string;
        x: number;
        y: number;
        w: number;
        h: number;
      };
    };
    recommended: [];
  };
};