はじめに
前回の記事で、PokeAPIを使ってポケモンの一覧データを取得しました。
今回は、選択したポケモンの詳細データを取得し、より豊富な情報を表示できるようにします。
APIのエンドポイントの使い方や、非同期処理の扱いについても解説します。
ポケモンの詳細なデータを取得する
App.js
import { useEffect, useState } from 'react';
import './App.css';
import { getAllPokemon, getPokemon } from './utils/pokemon';
function App() {
const initialURL = "https://pokeapi.co/api/v2/pokemon";
const [loading, setLoading] = useState(true);
const [pokemonData, setPokemonData] = useState([]);
useEffect(()=>{
const fetchPokemonData = async () => {
// 全てのポケモンデータを取得
let res = await getAllPokemon(initialURL);
// 各ポケモンの詳細なデータを取得
loadPokemon(res.results);
// console.log(res.results);
setLoading(false);
};
fetchPokemonData();
},[]);
const loadPokemon = async (data) => {
let _pokemonData = await Promise.all(
data.map((pokemon) => {
// console.log(pokemon);
let pokemonRecord = getPokemon(pokemon.url);
return pokemonRecord;
})
);
setPokemonData(_pokemonData);
};
console.log(pokemonData);
return (
<div className="App">
{loading ? (
<h1>ロード中・・・</h1>
) : (
<>
<h1>ポケモンのデータを取得しました</h1>
</>
)}
</div>
);
}
export default App;
pokemon.js
export const getAllPokemon = (url) => {
return new Promise((resolve, reject) => {
fetch(url)
.then((res) => res.json())
.then((data) => resolve(data));
});
};
export const getPokemon = (url) => {
return new Promise((resolve, reject) => {
fetch(url)
.then((res) => res.json())
.then((data) => {
console.log(data);
resolve(data);
});
});
};
小学生でも理解できるように説明してください。
📌 このコードの目的は?
このコードは、ポケモンの 一覧 を取得した後に、
各ポケモンの 詳細情報 も取得するプログラムだよ!
📍 1. 最初にポケモンの一覧を取得する (getAllPokemon)
まず、最初のAPI(https://pokeapi.co/api/v2/pokemon)にアクセスして、
「ポケモンの一覧」を取得 するよ。
export const getAllPokemon = (url) => {
return new Promise((resolve, reject) => {
fetch(url)
.then((res) => res.json()) // APIからJSONデータを受け取る
.then((data) => resolve(data)); // 取得したデータを返す
});
};
💡 ポイント!
fetch(url)→ APIにデータを取りに行く.then((res) => res.json())→ 取得したデータをJSON形式に変換.then((data) => resolve(data))→ データを返す
📍 2. ポケモン一覧の取得後に詳細データを取る
次に、useEffect を使ってデータを取得する処理を実行するよ。
useEffect(()=>{
const fetchPokemonData = async () => {
// ① 全てのポケモンデータを取得
let res = await getAllPokemon(initialURL);
// ② 各ポケモンの詳細なデータを取得
loadPokemon(res.results);
setLoading(false);
};
fetchPokemonData();
},[]);
💡 ポイント!
getAllPokemon(initialURL)でポケモンの一覧を取得する
→ 例えばこんなデータが取れる!{ "results": [ {"name": "bulbasaur", "url": "https://pokeapi.co/api/v2/pokemon/1/"}, {"name": "ivysaur", "url": "https://pokeapi.co/api/v2/pokemon/2/"}, {"name": "venusaur", "url": "https://pokeapi.co/api/v2/pokemon/3/"} ] }各ポケモンの「名前」と「詳細データのURL」が入っているよ!- 取得した
res.resultsをloadPokemon()に渡すloadPokemon()を呼び出して 詳細データを取得する
📍 3. ポケモンの詳細データを取得 (getPokemon)
次に、各ポケモンの 詳細データ を getPokemon を使って取得するよ!
export const getPokemon = (url) => {
return new Promise((resolve, reject) => {
fetch(url)
.then((res) => res.json())
.then((data) => {
console.log(data); // 取得したポケモンのデータを表示
resolve(data);
});
});
};
💡 ポイント!
getPokemon(pokemon.url)を呼び出すことで、
各ポケモンの詳細データ を取得するよ!- 例えば「フシギダネ」のデータはこんな感じ!
{ "id": 1, "name": "bulbasaur", "height": 7, "weight": 69, "sprites": { "front_default": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/1.png" } }ポケモンの名前・高さ・重さ・画像URLなどのデータが取れる!
📍 4. loadPokemon() でポケモン詳細データを取得
const loadPokemon = async (data) => {
let _pokemonData = await Promise.all(
data.map((pokemon) => {
let pokemonRecord = getPokemon(pokemon.url);
return pokemonRecord;
})
);
setPokemonData(_pokemonData);
};
💡 ポイント!
data.map((pokemon) => getPokemon(pokemon.url))data(ポケモン一覧)を1つずつ取り出して、getPokemon(url)を呼び出す!- 例えば、
getPokemon("https://pokeapi.co/api/v2/pokemon/1/"); getPokemon("https://pokeapi.co/api/v2/pokemon/2/"); getPokemon("https://pokeapi.co/api/v2/pokemon/3/");のように、ポケモンごとのURLにアクセスして詳細データを取得する!
Promise.all([...])で全てのデータを取得するまで待つawait Promise.all([...])を使うと、すべてのデータが取れるまで待機する ことができる!Promise.allを使わないと、データがバラバラに取得されてしまう ので注意⚠️
- 取得したデータを
setPokemonData(_pokemonData)で保存setPokemonDataを使って Reactのstateに保存 する- これでポケモンの詳細データが
pokemonDataに入る!
📍 5. pokemonData に保存されたデータを確認
console.log(pokemonData);
この pokemonData には、全てのポケモンの詳細情報が入っている!
例えば、こうなるはず👇
[
{
id: 1,
name: "bulbasaur",
height: 7,
weight: 69,
sprites: { front_default: "画像URL" }
},
{
id: 2,
name: "ivysaur",
height: 10,
weight: 130,
sprites: { front_default: "画像URL" }
},
{
id: 3,
name: "venusaur",
height: 20,
weight: 1000,
sprites: { front_default: "画像URL" }
}
]
💡 これで、ポケモンの 名前・高さ・重さ・画像 が取得できたね!
🎯 まとめ
✅ ポケモンの一覧を取る
let res = await getAllPokemon(initialURL);
✅ 各ポケモンの詳細データを取る
loadPokemon(res.results);
✅ ポケモンのデータを map() で取得する
let _pokemonData = await Promise.all(
data.map((pokemon) => getPokemon(pokemon.url))
);
✅ データを setPokemonData に保存
setPokemonData(_pokemonData);
🎯 こんなふうにイメージしよう!
🎣 魚を釣るみたいな流れ
getAllPokemon→ 大きな池の魚のリストをもらう(ポケモン一覧)loadPokemon→ それぞれの魚の種類を調べる(詳細データ取得)Promise.all→ 全部の魚が集まるまで待つ(全データがそろうまで待機)- データを
pokemonDataに保存して一覧表示!
🚀 これでコードが書けるようになる!
この仕組みがわかれば、 「一覧を取得して、各詳細データを取る」 というパターンのコードが書けるようになるよ!🔥
ポケモン以外のデータ(映画リスト、天気情報など)でも使えるから、ぜひ試してみよう!🎉