Apps

015-Poke picture book|Step3_ポケモンの詳細なデータを取得

はじめに

前回の記事で、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)

まず、最初のAPIhttps://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();
},[]);

💡 ポイント!

  1. 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」が入っているよ!
  2. 取得した res.resultsloadPokemon() に渡す
    • 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);
};

💡 ポイント!

  1. 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にアクセスして詳細データを取得する!
  2. Promise.all([...]) で全てのデータを取得するまで待つ
    • await Promise.all([...]) を使うと、すべてのデータが取れるまで待機する ことができる!
    • Promise.all を使わないと、データがバラバラに取得されてしまう ので注意⚠️
  3. 取得したデータを 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);

🎯 こんなふうにイメージしよう!

🎣 魚を釣るみたいな流れ

  1. getAllPokemon → 大きな池の魚のリストをもらう(ポケモン一覧)
  2. loadPokemon → それぞれの魚の種類を調べる(詳細データ取得)
  3. Promise.all → 全部の魚が集まるまで待つ(全データがそろうまで待機)
  4. データを pokemonData に保存して一覧表示!

🚀 これでコードが書けるようになる!

この仕組みがわかれば、 「一覧を取得して、各詳細データを取る」 というパターンのコードが書けるようになるよ!🔥
ポケモン以外のデータ(映画リスト、天気情報など)でも使えるから、ぜひ試してみよう!🎉

-Apps