개인과제에서 rotation 페이지를 구현하면서 까다로운 과정을 겪게 되었다…🫠
현업에서 이런 경우가 많다고 해서… 미래의 나를 위한 정리글을 작성해보기로..했다..!
rotation 기능구현 (데이터 가져오기)
구현사항
rotation page의 페이지 설정은 아래와 같다.
이 내용을 기반으로 api
에서 어떤 데이터를 주는지 확인해보려고 코드를 작성했다.
"use client"; //CSR 렌더링이므로 작성 필수!
import { useEffect, useState } from "react";
import { getChampionRotation } from "@/utils/riotApi";
export default function ChampionRotationPage() {
const [rotation, setRotation] = useState(null);
const [error, setError] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function fetchRotation() {
try {
const data = await getChampionRotation();
console.log("API 응답 데이터:", data); // 콘솔확인
setRotation(data);
} catch (error) {
console.error("Fetch Error:", error);
setError("로테이션 데이터를 가져오는 중 문제가 발생했습니다.");
} finally {
setLoading(false);
}
}
fetchRotation();
}, []);
if (error) {
return <div>Error: {error}</div>;
}
if (!rotation) {
return <div>Loading...</div>;
}
return (
<div>
<h1>챔피언 로테이션</h1>
</div>
);
}
콘솔창 확인하기 ✅
이렇게 작성하고 콘솔창을 확인했는데 난 내가 api
주소를 잘못 불러온 줄 알았다….ㅋㅋ
이름이라던가.. 뭐 캐릭터 설명도 없이 사진처럼 이상한 숫자만 주르륵 떴고 freeChampionIds
라는 내가 전혀 작성하지 않았던게 있어서 당황스러웠다.
튜터님한테 찾아가서 해결방법을 물어보았고… 꽤나 까다로운 작업이 될 수 있겠다는 생각이 들었다…ㅎ
Champion
데이터를 주는 json api
를 보면 위 사진처럼 캐릭터(Aatrox) 안에 데이터들이 쭉 담겨진 걸 볼 수 있다. 아까 봤던 숫자들은 그 주에 로테이션 된 캐릭터들의 고유 id
이기 때문에 그 id
값을 보고 전체 캐릭터 목록 데이터에서 일치하는 걸 찾아줘야한다는거다.
💡 정리하면 다음과 같다.
id
를 확인 후 데이터 받아온다. → freeChampionIds
Champion data
에서 동일한 값을 가진 것만 find
메소드로 찾아서 후 배열로 담는다.freeChampionIds
가 주는 데이터 타입은 number
, Champion
데이터는 string
이므로 형변환도 해야한다."use client";
import { useEffect, useState } from "react";
import { getChampionRotation } from "@/utils/riotApi";
import { fetchChampionList } from "@/utils/serverApi"; // 챔피언 목록
type ChampionData = { // 타입 명시하기
id: string;
title: string;
name: string;
image: { full: string };
};
export default function ChampionRotationPage() {
const [rotation, setRotation] = useState<number[]>([]); // id , 배열로 담기
const [champions, setChampions] = useState<{
[key: string]: ChampionData;
}>({}); // 챔피언 목록
const [error, setError] = useState<string | null>(null);
const [loading, setLoading] = useState<boolean>(true);
useEffect(() => {
async function fetchData() {
try {
const rotationData = await getChampionRotation();
**console.log(rotationData); // ✅ 수정한 부분
setRotation(rotationData.freeChampionIds);
const championData = await fetchChampionList();
**console.log(championData); // ✅ 수정한 부분
setChampions(championData);
} catch (error) {
console.error("Fetch Error:", error);
setError("로테이션 데이터를 가져오는 중 문제가 발생했습니다.");
} finally {
setLoading(false);
}
}
fetchData();
}, []);
if (loading) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error: {error}</div>;
}
return (
<div>
<h1>챔피언 로테이션</h1>
<div>
{rotation.map((id) => {
const champion = Object.values(champions).find( //find 메소드 사용
(champion) => champion.id === id.toString() //rotation의 id 문자열로변환
);
console.log(champion)
if (!champion) {
return null;
}
return (
<div key={champion.id}>
<img
src={`https://ddragon.leagueoflegends.com/cdn/14.19.1/img/champion/${champion.id}.png`}
alt={champion.name}
width={100}
height={100}
/>
<h3>{champion.name}</h3>
<p>{champion.title}</p>
</div>
);
})}
</div>
</div>
);
}
우선 rotation
과 champions
에는 내가 받고자 하는 데이터가 잘 담겨져왔다.
이제 여기서 find
메소드로 일치하는 데이터만 뽑아오면 되었다!
return (
<div>
<h1>챔피언 로테이션</h1>
<div>
{rotation.map((id) => {
const champion = Object.values(champions).find( //find 메소드 사용
(champion) => champion.id === id.toString() //rotation의 id 문자열로변환
);
console.log(champion) // 🚨 undefined
if (!champion) {
return null;
}
// ** 생략 **
)
그런데 자꾸 데이터가 뜨지 않았고 콘솔로 확인해보니까 champion
값이 undefined
가 떴다.
find
메소드를 적용하기 전의 데이터는 잘 불러와지는지 확인해봤다.
일단 전체 데이터는 원하는대로 잘 담겨져 왔고 문제는 find
를 적용하는 부분이라는걸 확인했다.
주석처리한 것처럼 코드를 작성해서 데이터를 확인했다.
튜터님 말대로 id
값을 비교하면 된다~ 해서 제대로 안 보고 id
를 각각 비교했는데 콘솔로 보면 멍청한 짓을 하고 있었다는 걸 알 수 있다…
rotation
에서는 id
가 맞지만 champion
데이터에서 비교할 건 id가 아니라 key
값이었다… 😇
// ** 중략 **
return (
<div>
<h1>챔피언 로테이션</h1>
<div>
{rotation.map((id) => {
console.log("로테이션 챔피언 ID:", id);
const champion = Object.values(champions).find((champion) => {
return champion**.key** === id.toString(); //id가 아니라 key!!
});
if (!champion) {
return null;
}
return (
<div key={champion.id}>
<img
src={`https://ddragon.leagueoflegends.com/cdn/14.19.1/img/champion/${champion.id}.png`}
alt={champion.name}
width={100}
height={100}
/>
<h3>{champion.name}</h3>
<p>{champion.title}</p>
</div>
);
})}
</div>
</div>
);
이렇게 수정해주니까 기다렸다는듯이 촤라락 데이터가 브라우저에서 펼쳐졌다..ㅎ
늘 느끼는 교훈… api
데이터를 불러올 때는 콘솔을 꼼꼼하게 보자…!!