useEffect useState ようやく理解できた【Day 96 of 100】

by

in

, ,

ポケモン図鑑アプリでReact学習中

https://kiyo4810.github.io/pokemon-app

やったね。↑ 公開もできた!

イマイチ理解できなかったuseStateとuseEffect

だったが、以下、単純なカウンター機能?アプリ?をAIに教わる通り埋め込んだら理解できた

追加機能のカウンター

useState

// count:中身が変わると再レンダリングされる特別な変数
// setCount:更新用の関数。値を書き換える専用リモコン。
// count = 1と代入はNG。setCount(1)やsetCount(count+1) とすべし
// ここでの0は初期値
const [count, setCount] = useState(0);

useEffect

  /*
   * useEffectは、第一引数にcallbackを入れて、第二引数に依存する値の配列を入れる
   * 依存する値が変更される度にcallbackが実行される
   */
  useEffect(() => {
    console.log(count);
  }, [count]);

onClick で クリックしたらonClick内の関数実行→ useStateの更新関数実行→ countが0から1へ変更→useEffectの第二引数の配列内のcountが更新されてuseEffectの関数発火!→コンソールにcountが表示される

 return (
    <div className="Counter">
      <p>{count}</p>
      <button onClick={() => setCount(count + 1)}>カウント</button>
      <hr />
    </div>
  );

本来の機能、ポケモン図鑑 by ポケモンAPI

import { useEffect, useState } from 'react';
import './App.css';
import { getAllPokemon, getPokemon } from './utils/pokemon';
import Card from './components/Card/Card';
function App() {
const initialURL = 'https://pokeapi.co/api/v2/pokemon';
const [loading, setLoading] = useState(true);
const [pokemonData, setPokemonData] = useState([]);
/*
* useEffectは、第一引数にcallbackを入れて、第二引数に依存する値の配列を入れる
* 依存する値が変更される度にcallbackが実行される
*/
useEffect(() => {
const fetchPokemonData = async () => {
// すべてのポケモンデータを取得
// ① データを取ってくる(時間がかかる作業)
let res = await getAllPokemon(initialURL);
// 各ポケモンの詳細なデータを取得
// ② 詳細データを取ってくる(これも時間がかかる作業)
await loadPokemon(res.results);
// ③ ここがポイント!
// 上の ① と ② が終わるまで、プログラムはここで「待機」します。
// 無事にデータが全部揃ったら、ようやく次の行に進めます。
setLoading(false); // ← ここであなたが「よし、終わったから false にして!」と命令した
};
fetchPokemonData();
// #### 空の配列を第二引数に仕込む重要な意味
// 「いいかいReactくん。これから loading が false になったり、
// ポケモンデータが書き換わったりユーザーが文字入力したりして、
// 何度も App 関数をやり直すことになるだろう。
// でも、この『APIからデータを取ってくる作業』だけは、
// 最初の一回だけで十分だから、2回目以降は無視してスルーしてくれよ!」
}, []);
const loadPokemon = async (data) => {
// allの意味は今回、20件すべてのfetchが終わるまでの意味。
// Promise.all()カギ括弧の中には配列を入れる
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>
) : (
<>
<div className="pokemonCardContainer">
{pokemonData.map((pokemon, i) => {
return <Card key={i} pokemon={pokemon} />;
})}
</div>
</>
)}
</div>
);
}
export default App;
/* ================================================================
【完全解説:ポケモン図鑑アプリが動く 4つのフェーズ】
================================================================
第1フェーズ:準備(アプリが立ち上がった瞬間)
--------------------------------------------------
プログラムが読み込まれると、State(データの保管箱)が用意されます。
・loading: 最初は true(あなたが「今は準備中だよ!」と定義した状態)
・pokemonData: 最初は [](空っぽの配列)
この時点では、画面には「ロード中・・・」だけが表示されています。
第2フェーズ:useEffect の発動(最初の一回だけ実行)
--------------------------------------------------
画面に「ロード中」が出た直後、useEffect が動き出します。
・fetchPokemonData() が実行され、APIから「20件の名前とURLのリスト」を取得。
・名前だけでは画像がないため、次の詳細データ取得ステップへバトンタッチします。
第3フェーズ:詳細データの「一斉取得」(Promise.all)
--------------------------------------------------
・data.map で20匹分の「詳細情報を取ってきてね」という予約リストを作成。
・Promise.all を使い、「20匹全員分が揃うまで待つよ!」と一斉に取得(Fetch)。
・全員分が揃った瞬間に、保管箱(setPokemonData)へドサッと保存します。
・最後に setLoading(false) を実行。ここで「準備完了!」のスイッチを押します。
第4フェーズ:再レンダリング(画面の完成)
--------------------------------------------------
Stateが更新されたので、Reactがもう一度画面を描き直します。
・loading が false になったので、画面の表示が「カードを表示する側」に切り替わる。
・保管箱のデータを1つずつ取り出し、<Card /> コンポーネントを20枚並べます。
・これで、画面にポケモンたちがズラッと並んで完成です!
💡 初学者が「おっ」となるポイント
--------------------------------------------------
1. なぜ async/await を使うの?
API通信は返事に時間がかかるため、「返事が来るまで次の行に行かずに待っててね」
という指示です。これがないとデータが届く前に次の処理が進んでエラーになります。
2. なぜわざわざ loadPokemon を分けるの?
「全体のリストを取る作業」と「1匹ずつの詳細を取る作業」は別物だからです。
分けて書くことで、後で読み返した時に理解しやすくなります。
3. console.log(pokemonData) が2回動くのはなぜ?
1回目は「空のとき(最初の描画)」、2回目は「データが入ったとき(再描画後)」
に動くからです。Reactが状態の変化を正しく検知している証拠です!
この「データを取ってきて、Stateに入れ、画面を切り替える」という流れは、
モダンなWeb開発で必ず使う【最強の王道パターン】です。
================================================================ */

本日の成果

https://kiyo4810.github.io/pokemon-app


コメントを残す

猫でデザインとプログラミングを学ぶをもっと見る

今すぐ購読し、続きを読んで、すべてのアーカイブにアクセスしましょう。

続きを読む