サムネイルの画像

PokeAPI×Reactで作成したポケモン図鑑を日本語表記にする方法

React

API

はじめに

今回Udemyの講座でReactでポケモン図鑑を作るというものを受講しました。ですが完成したものは英語表記となっており日本語表記にしたいなと思い、Jsonのデータを探し回って見つけたのでその過程を残しておこうと思います。

今回受講したUdemyの講座

とても好きなUdemy講師の方でYouTubeなどでも情報発信してくださっています。

始める前に

この記事はポケモン図鑑の作り方を説明するものではなく、
英語表記から日本語表記にするためのものです。

環境

・react @18.2.0
・npm 9.5.0
・node v18.15.0

PokeAPIとは

ポケモンの情報を提供してくれているAPIであり、基本的に英語ベースとなっています。
https://pokeapi.co/api/v2/pokemon/ のURLにアクセスすると20件のポケモンデータがJson形式で返されており、実際に見てみるとわかりますが1281のポケモンのうちの20を表示していて、各ポケモンの英語での名前とより詳細なデータがあるurlというキーのプロパティが存在する。results[0].nameという風に指定すると図鑑番号1番のフシギダネの英語名が取得できるという具合です。

まず、英語名の表示の方法

では英語名を取得するコードと、日本語名を取得するコードを実際に見ながら確認していきます。

↓ 両言語共通のPokeAPIからデータを持ってくるための下準備(無視でOK!!)
const pokeApiUrl = "https://pokeapi.co/api/v2/pokemon/";
const [pokemonData, setPokemonData] = useState([]);

//非同期でurlに与えたURLからデータを取得する関数
const getAllPokemon = (url) => {
    return new Promise((resolve,reject) => {
        fetch(url)
        .then((res) => res.json())
        .then((data) => resolve(data))
    })
}
const getPokemon = (url) => {
    return new Promise((resolve,reject) => {
        fetch(url)
        .then((res) => res.json())
        .then((data) => resolve(data))
    })
}

//map関数で一つ一つ各ポケモンのurlにアクセスして詳細を取得してstateに格納する関数
const loadPokemon = async (data) => {
    let _pokemonData = await Promise.all(
      data.map((pokemon) => {
        let pokemonRecord = getPokemon(pokemon.url);
        return pokemonRecord;
      })
    );
    setPokemonData(_pokemonData);
  };

//上記の関数を一度だけ実行する
useEffect(() => {
    const fetchPokemonData = async () => {
      let res = await getAllPokemon(pokeApiUrl);
      loadPokemon(res.results);
    };
    fetchPokemonData();
  }, []);

これでpokemonDataの中に配列として各ポケモンの詳細なデータが格納されたことになります。
ですのでpokemonDataに対してmap関数で名前を指定して表示してあげれば英語名の表示は完了です。

pokemonDataに入っているJsonデータの構造
"species": {
		"name": "bulbasaur",
		"url": "https://pokeapi.co/api/v2/pokemon-species/1/"
	},
↓ 英語名の名前を取得するコード
return (
    <>
              <div>
        {pokemonData.map((pokemon) => {
          return <p>{pokemon.species.name}</p>
        })}
       </div>
    </>
  );

となり、上記のJsonデータを見ていただくとわかる通りspeciesの中に英語名と、更に詳細なデータが格納されているurlがありますのでspecies.urlにアクセスすると様々な言語のフレーバーテキスト、何ポケモンなのか、ポケモンの名前などがありますので、その中の一部を記載するとこうなります。

↓ species.urlにアクセスした中身の一部
"names":[
	  {
	     "language": {
			"name": "ja-Hrkt",
			"url": "https://pokeapi.co/api/v2/language/1/"
			},
	     "name": "フシギダネ"
		},
		{
	     "language": {
			"name": "roomaji",
			"url": "https://pokeapi.co/api/v2/language/2/"
			},
	     "name": "Fushigidane"
		},

ここまで来れば、names.language.name === "ja-Hrkt"もしくは"ja"に合致するものをfind関数等で見つけてそのnames.nameを出力すればいいんだとなりますね。

日本語で表示する方法

先ほど説明した通り、ポケモンの名前に限らず英語名で欲しい情報にアクセスできている場合はそこのurlというキーにアクセスして、その中の"ja-Hrkt"もしくは"ja"に合致するものをfind関数等で見つけて表示すれば良いということになります。

↓ 日本語のポケモンの名前を取得するコード
const [pokemonName, setPokemonName] = useState([]);

//複数個になると変わる部分
let pokemonNameDetail = pokemon.species.url;

const loadPokemonName = async (data) => {
  let response = await fetch(data);
  let result = await response.json();
  let jaName = result.names.find(name => name.language.name === "ja").name;
  setPokemonName(jaName);
};

 useEffect(() => {
    loadPokemonName(pokemonNameDetail);
  },[])

return (
    <div className="card">
      <h4 className="cardNames">{pokemonName}</h4>
    </div>
  );

今回はjaと一致するもので探して、日本語で表示されるようになりました。

配列で提供されているものを日本語で表示する方法

名前の時としようとしていることは一緒ですが、先ほどの一つしかないものは下記の通りなのでそのままダイレクトでアクセスできますが、「ほのお・ひこう」のようなタイプや複数パターンの特性を持つポケモンたちは配列で要素を渡されますので、上の日本語の名前を取得するコードの部分をmap関数などで一つ一つ取り出して与えていく必要があります。

↓ 一つしかデータが入っていない要素のJsonデータの構造
"species": {
		"name": "bulbasaur",
		"url": "https://pokeapi.co/api/v2/pokemon-species/1/"
	},
↓ 複数個のデータが配列になっている要素のJsonデータの構造
"types": [
          {
	"slot": 1,
	"type": {
	           "name": "grass",
	            "url": "https://pokeapi.co/api/v2/type/12/"
	}
           },
           {
	"slot": 2,
	"type": {
	            "name": "poison",
	            "url": "https://pokeapi.co/api/v2/type/4/"
	}
            }
],
↓ 複数個のデータ(タイプ)を日本語表示するためのコード
// タイプ一つ一つの詳細なデータがあるJsonのurlを取得
  let resPokemonTypes = pokemon.types.map((v) => {
    let typesURL = v.type.url;
    return typesURL;
  });

  // 引数として与えられたurlの中から"ja"にマッチするものを取得してstateに格納する関数
  const loadPokemonType = async (data) => {
    let _pokemonType = await Promise.all(
      data.map(async (pokemon) => {
        let pokemonTypeDetail = await getPokemonType(pokemon);
        let jaName = pokemonTypeDetail.names.find(name => name.language.name === "ja").name;
        return jaName;
      })
    );
    let joinedTypes = _pokemonType.join(" / ");
    setPokemonTypeURL(joinedTypes);
  };
  
  useEffect(() => {
    loadPokemonType(resPokemonTypes);
  },[])

完成品

日本語表記にしました完成品がこちらとなります

まとめ

今回はポケモン図鑑を日本語にということで、結論は深いところに置いてあっただけという感じではあったのですが動画に習うだけでなく一から自分でマップ関数等を用いて非同期を書いたりと、そのまま復習になりますので是非一つの学習の案として考えてみていただければと思います。ここまで見て頂きありがとうございました、拙い文失礼いたしました。