はじめに
こんにちは!
未経験からエンジニアを目指して学習中のhayateです。
今回は useState
と useEffect
を使って外部APIからデータを取得し、
画面に表示するミニアプリ を作ります。
初心者の方がつまずきやすいポイント(非同期処理・APIの扱い)を押さえながら、
2時間以内で完成できるシンプルな実装例を紹介します。
完成形はこんな感じです👇
今回作るアプリの概要
- ユーザーIDを入力 → ボタン押下でデータ取得
- 取得結果をカード形式で一覧表示
- ローディング中の表示あり
- 無料のサンプルAPI JSONPlaceholder を利用
⚙️ 開発環境と事前準備
- Node.js v◯◯
- npm v◯◯
- Vite(またはCreate React Appでも可)
- JSONPlaceholder(https://jsonplaceholder.typicode.com/)
2.実装の流れ
- プロジェクト作成(Vite)
- 必要な状態(useState)を定義
- ボタン押下でfetch APIを呼び出す
- ローディング表示とエラー処理を追加
- カード形式でデータを表示
コードの全体図を提示しつつ、プロジェクト作成のフェーズから行っていきます。
コード全体(完成版)
// 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モードに切り替え。
そして、ターミナル上に以下の順番でコードを記述します。
💻 記述する順番
① npm create vite@latest react-api-sample --template react
→ 最新版のViteを使って新規プロジェクトを作成するためのコード
② cd react-api-sample
→ プロジェクトフォルダに移動
③ npm install
→ 必要なパッケージをインストール
④ npm run dev
→ 開発サーバーを起動
前述した通りにターミナルを記述すると、ターミナルに http://localhost:5173 という
URLが表示されるので、クリックしてブラウザで開きます。
ブラウザで 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 の定義を追加します。
App.jsxへ保存ができました。
5.ボタン押下でfetch APIを呼び出す(エラー対応)
ボタンをクリックしたらAPIを呼び出し、
データを取得する処理を追加します。
ここから、ターミナルを出し、bashモードに切り替え。
「npm run dev」を記述→ URLをクリックしてブラウザで開きます。
ここで、エラー表示がなされてURLが出ませんでした。
chatGPTに問いかけてみたところ、プロジェクト作成がなされていなかったようです。
中身を全部消して新規作成する形で進めてみます。
ということでまずは、ターミナルに「rm -rf react-api-sample」と入力。
react-api-sampleの初期化が確認できたら、改めてViteプロジェクトを作成したいので
bash上に「npm create vite@latest react-api-sample」と入力。
◆ Select a framework:
│ ● Vanilla
│ ○ Vue
│ ○ React
│ ○ Preact
│ ○ Lit
│ ○ Svelte
│ ○ Solid
│ ○ Qwik
│ ○ Angular
│ ○ Marko
│ ○ Others
ターミナルにこのような表示がみられたので、
矢印キー ↓ を使って「React」、「JavaScript」の順で
エンターキーを押していきます。
Scaffolding project in ./react-api-sample...
Done. Now run:
cd react-api-sample
npm install
npm run dev
という表示が見られたのでプロジェクトの作成は完了しました。
5.ボタン押下でfetch APIを呼び出す
エラー対応もできたので、ここからこのフェーズの本題へ入ります。
この状態ではまだ データ取得ボタン+結果表示 は実装されていないので、
「loading / error / data:」も画面に表示できるように、次のように設定します。
VSCodeにて、App.tsxファイルに上記のコードを記述することで、
ブラウザ上では次のように表示されます。
この表示がされたのを確認した上で、
・「Countボタン」をクリックしてcount:0の数値が変わるか
・「データ取得」をクリックして結果表示がされるか
これらが確認できればこのフェーズは完了です。
スクショ画像を添付するとこんな感じになります。
6.ローディング表示とエラー処理を追加
このフェーズは「ボタン押下でfetch APIを呼び出す」までのフェーズで
コードのベースができているので、やることはシンプルです。
まず、ローディング表示については「データ取得」をクリックした瞬間に
「loading: データ読み込み中...」と表示されればOKです。
ちなみに「loading: データ読み込み中...」と表示されたものがこちらです。
次にエラー処理を追加についてです。
「ボタン押下で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
として、コードを保存→リロードすると以下のようになりました。
「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>
)}
に置換するという至ってシンプルな内容です。
置換してリロード、データ取得をクリックします。
また、ローディング表示については、前フェーズの「ローディング表示」とやることは一緒で
「データ取得」をクリックした瞬間に「loading: データ読み込み中...」
と表示されるかどうかを確認します。以下のスクショ画像のように確認ができました。
そして、最後にエラー処理の工程です。
こちらも前フェーズとやることは一緒で
App.tsxファイル内のURLをダミーURLへ置換して、
保存→リロードすると以下のようになりました。
「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に組み込んでみた」
で記事を作成していきたいと思います。
最後まで読んでいただき、ありがとうございました。