[Next.js] map is not a function

정다롱·2024년 9월 30일

내일배움캠프 TIL

목록 보기
26/39

💥 Next.js ts 배열 map 오류


발생 문제

Riot Api를 사용하여 받아온 아이템 목록을 하나씩 출력하기 위해 map 사용했으나
Error: items?.map is not a function
오류가 출력됨


오류 발생 부분

// page 컴포넌트
const ItemsPage = async () => {
  const version = await fetchVersion();
  const items = await fetchItemList(version);

  return (
    <> // 이부분 map이 안됨
      {items.map((item) => (
        <div key={item.id}>{item.name}</div>
      ))}
    </>
  );
};

// fetchItemList 함수
export const fetchItemList = async (version: string) => {
  const res = await fetch(
    `https://ddragon.leagueoflegends.com/cdn/${version}/data/ko_KR/item.json`
  );
  const items: Item[] = await res.json();

  return items;
};

items: Item[] 으로 배열 지정하고 컴포넌트 코드에서 마우스 올렸을 때 타입로 Item[]으로 잘 뜨나 map오류가 계속해서 발생했다.


문제 원인

Riot API의 응답 데이터는 KEY(ID) : VALUE(정보) 의 객체 형태로 전달된다.
애초에 응답 데이터가 배열이 아니었기 때문에 타입과 상관없이 오류가 발생한 부분.
데이터 반환값 참고


문제 해결

Object.entries 를 사용해서 key, value를 함께 배열로 만들었다.
id값이 생김에 따라 새로운 type도 지정해주었더니 깔끔하게 해결됐다.
그냥 values 써서 정보만 배열로 만들어도 되는데, map을 돌리고 key값에 고유한 값을 넣기 위해 id를 포함했다. (이름이 중복되는 아이템이 있음)

export interface ItemWithId extends Item {
  id: string; // 아이템 ID 추가
}

export const fetchItemList = async (version: string): Promise<ItemWithId[]> => {
  const res = await fetch(
    `https://ddragon.leagueoflegends.com/cdn/${version}/data/ko_KR/item.json`
  );

  const data = await res.json();

// 새 타입으로 지정해주기
  const items: ItemWithId[] = Object.entries(data.data).map(([id, item]) => ({
    ...(item as Item), 
    // 기본적으로 item 타입이 unknown이라서 스프레드 연산자를 쓰면 경고문이 나와서 타입 지정
    id,
    // 기존 값 안에 id 합체시키기
  }));

  return items;
};

0개의 댓글