0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

「React × useState × useEffectでAPIデータを表示してみた」 【学習記録】

Last updated at Posted at 2025-08-16

はじめに

こんにちは!
未経験からエンジニアを目指して学習中のhayateです。

今回は useStateuseEffect を使って外部APIからデータを取得し、
画面に表示するミニアプリ
を作ります。
初心者の方がつまずきやすいポイント(非同期処理・APIの扱い)を押さえながら、
2時間以内で完成できるシンプルな実装例を紹介します。

完成形はこんな感じです👇

スクリーンショット 2025-08-16 23.18.41.png


今回作るアプリの概要

  • ユーザーIDを入力 → ボタン押下でデータ取得
  • 取得結果をカード形式で一覧表示
  • ローディング中の表示あり
  • 無料のサンプルAPI JSONPlaceholder を利用

⚙️ 開発環境と事前準備


2.実装の流れ

  1. プロジェクト作成(Vite)
  2. 必要な状態(useState)を定義
  3. ボタン押下でfetch APIを呼び出す
  4. ローディング表示とエラー処理を追加
  5. カード形式でデータを表示

コードの全体図を提示しつつ、プロジェクト作成のフェーズから行っていきます。


コード全体(完成版)

// App.jsx
import { useState } from "react";

function App() {
  const [query, setQuery] = useState("");
  const [data, setData] = useState([]);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  const fetchData = async () => {
    if (!query) {
      alert("User IDを入力してください");
      return;
    }
    setLoading(true);
    setError(null);
    try {
      const res = await fetch(
        `https://jsonplaceholder.typicode.com/posts?userId=${query}`
      );
      if (!res.ok) throw new Error("API取得エラー");
      const json = await res.json();
      setData(json);
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div style={{ padding: "20px", fontFamily: "sans-serif" }}>
      <h1>React × useState × fetch API</h1>
      <div style={{ marginBottom: "10px" }}>
        <input
          type="number"
          value={query}
          onChange={(e) => setQuery(e.target.value)}
          placeholder="User IDを入力"
          style={{ padding: "6px", marginRight: "8px" }}
        />
        <button onClick={fetchData} style={{ padding: "6px 12px" }}>
          データ取得
        </button>
      </div>

      {loading && <p>読み込み中...</p>}
      {error && <p style={{ color: "red" }}>エラー: {error}</p>}

      <div>
        {data.map((item) => (
          <div
            key={item.id}
            style={{
              border: "1px solid #ccc",
              borderRadius: "8px",
              padding: "10px",
              marginBottom: "10px",
            }}
          >
            <h3>{item.title}</h3>
            <p>{item.body}</p>
          </div>
        ))}
      </div>
    </div>
  );
}

export default App;

3.プロジェクト作成(Vite)

VSCode内で進めていくので、まずはフォルダー作成から。
今回のテーマに沿ってフォルダー名は「react-api-sample」と設定。

VSCodeを開いてターミナルを出し、bashモードに切り替え。

スクリーンショット 2025-08-14 8.37.54.png

そして、ターミナル上に以下の順番でコードを記述します。


💻 記述する順番

① npm create vite@latest react-api-sample --template react  
   → 最新版のViteを使って新規プロジェクトを作成するためのコード

② cd react-api-sample  
   → プロジェクトフォルダに移動

③ npm install  
   → 必要なパッケージをインストール

④ npm run dev  
   → 開発サーバーを起動

前述した通りにターミナルを記述すると、ターミナルに http://localhost:5173 という
URLが表示されるので、クリックしてブラウザで開きます。

スクリーンショット 2025-08-14 8.42.26.png

ブラウザで http://localhost:5173 を開き、
初期画面が表示されれば準備完了です。

4.必要な状態(useState)を定義

useStateの定義を設定する前に、「react-api-sample」の構成に必要な
フォルダーやファイルは以下の通りになるように設定します。

react-api-sample/
├─ node_modules/        # 依存パッケージ
├─ public/              # 静的ファイル(画像など)
├─ src/                 # ソースコード
│  ├─ assets/           # 画像やCSS
│  ├─ App.css           # Appコンポーネント用のCSS
│  ├─ App.jsx           # メインコンポーネント(ここを編集)
│  ├─ index.css         # 全体のCSS
│  └─ main.jsx          # Reactアプリのエントリーポイント
├─ .gitignore
├─ index.html           # HTMLのひな形
├─ package.json         # 依存関係やスクリプト
├─ vite.config.js       # Viteの設定
└─ README.md

ここまで下準備ができた上で、useStateの定義のフェーズへ。
App.jsx の中に useState の定義を追加します。

スクリーンショット 2025-08-14 20.02.18.png

App.jsxへ保存ができました。

5.ボタン押下でfetch APIを呼び出す(エラー対応)

ボタンをクリックしたらAPIを呼び出し、
データを取得する処理を追加します。

スクリーンショット 2025-08-14 20.02.18.png

ここから、ターミナルを出し、bashモードに切り替え。
「npm run dev」を記述→ URLをクリックしてブラウザで開きます。

スクリーンショット 2025-08-14 20.44.03.png

ここで、エラー表示がなされてURLが出ませんでした。
chatGPTに問いかけてみたところ、プロジェクト作成がなされていなかったようです。

中身を全部消して新規作成する形で進めてみます。
ということでまずは、ターミナルに「rm -rf react-api-sample」と入力。

react-api-sampleの初期化が確認できたら、改めてViteプロジェクトを作成したいので
bash上に「npm create vite@latest react-api-sample」と入力。

スクリーンショット 2025-08-14 23.08.03.png

◆  Select a framework:
│  ● Vanilla
│  ○ Vue
│  ○ React
│  ○ Preact
│  ○ Lit
│  ○ Svelte
│  ○ Solid
│  ○ Qwik
│  ○ Angular
│  ○ Marko
│  ○ Others

ターミナルにこのような表示がみられたので、
矢印キー ↓ を使って「React」、「JavaScript」の順で
エンターキーを押していきます。

スクリーンショット 2025-08-14 23.09.04.png

Scaffolding project in ./react-api-sample...
Done. Now run:
cd react-api-sample
npm install
npm run dev

という表示が見られたのでプロジェクトの作成は完了しました。

5.ボタン押下でfetch APIを呼び出す

エラー対応もできたので、ここからこのフェーズの本題へ入ります。

スクリーンショット 2025-08-15 23.39.22.png

この状態ではまだ データ取得ボタン+結果表示 は実装されていないので、
「loading / error / data:」も画面に表示できるように、次のように設定します。

スクリーンショット 2025-08-16 22.33.41.png

VSCodeにて、App.tsxファイルに上記のコードを記述することで、
ブラウザ上では次のように表示されます。

スクリーンショット 2025-08-16 22.38.36.png

この表示がされたのを確認した上で、

・「Countボタン」をクリックしてcount:0の数値が変わるか
・「データ取得」をクリックして結果表示がされるか

これらが確認できればこのフェーズは完了です。
スクショ画像を添付するとこんな感じになります。

スクリーンショット 2025-08-15 23.40.53.png

6.ローディング表示とエラー処理を追加

このフェーズは「ボタン押下でfetch APIを呼び出す」までのフェーズで
コードのベースができているので、やることはシンプルです。

まず、ローディング表示については「データ取得」をクリックした瞬間に
「loading: データ読み込み中...」と表示されればOKです。
ちなみに「loading: データ読み込み中...」と表示されたものがこちらです。

スクリーンショット 2025-08-16 22.14.34.png

次にエラー処理を追加についてです。
「ボタン押下でfetch APIを呼び出す」の時のApp.tsxファイル内の13、14行目の

try {
      const res = await fetch('https://jsonplaceholder.typicode.com/posts/1');

の中のURLをダミーのURLに変えることで、意図的にエラーを起こす工程です。
今回はダミーのURLを https://jsonplaceholder.typicode.com/posts/INVALID
として、コードを保存→リロードすると以下のようになりました。

スクリーンショット 2025-08-16 22.23.16.png

「error: HTTPエラー: 404」の表示が見られたので、このフェーズは完了です。

7.カード形式でデータを表示

このフェーズでは「データ取得」をクリックすると、見た目がカードっぽい囲みを
表示させるための最後の仕上げの工程になります。

VSCodeでやることは、App.tsxの41行目の

{data && <pre>{JSON.stringify(data, null, 2)}</pre>}

このコードを

{data && (
  <div style={{
      border: '1px solid #ccc',
      borderRadius: '8px',
      padding: '16px',
      marginTop: '16px',
      boxShadow: '0 2px 5px rgba(0,0,0,0.1)'
  }}>
      <h3>{data.title}</h3>
      <p>{data.body}</p>
      <small>User ID: {data.userId}</small>
  </div>
)}

に置換するという至ってシンプルな内容です。
置換してリロード、データ取得をクリックします。

スクリーンショット 2025-08-16 23.18.41.png

また、ローディング表示については、前フェーズの「ローディング表示」とやることは一緒で
「データ取得」をクリックした瞬間に「loading: データ読み込み中...」
と表示されるかどうかを確認します。以下のスクショ画像のように確認ができました。

スクリーンショット 2025-08-16 23.20.35.png

そして、最後にエラー処理の工程です。

こちらも前フェーズとやることは一緒で
App.tsxファイル内のURLをダミーURLへ置換して、
保存→リロードすると以下のようになりました。

スクリーンショット 2025-08-16 23.25.29.png

「error: HTTPエラー: 404」の表示が見られたので、このフェーズは完了です。

8. 学んだこと・つまずいた点

学んだこと:
 ・useState と useEffect を使って API からデータを取得する方法
 ・非同期処理を try...catch で囲むことでエラーを検知させる方法
 ・JSON を必要な項目を抜き出してカード形式にすることで、見やすいUIにできた

つまずいたこと:
 ・画面が表示されない(「Next.js 形式とVite形式の違い」で混乱)
 ・データの表示方法(title や body を個別に表示する方法が分からなかった)
 ・スタイルの適用方法(「JSONをカード形式にする」の記述場所で迷った)

9. まとめ

今回は画面が表示されないエラーにずっと苦戦しましたが、
「状態管理(useState)」+「副作用(useEffect)」+「非同期処理(fetch)」
を通して、シンプルなデータ表示が体験できて、とても勉強になりました。

もし同じように「Reactを始めてみたいけど、
まず何を作ればいいのかわからない…」という方の参考になれば幸いです!

次回は 「v0で作ったUIをNext.jsに組み込んでみた」
で記事を作成していきたいと思います。

最後まで読んでいただき、ありがとうございました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?