2
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?

第4回:【React連携】GETとPOSTでデータを送受信!API連携アプリ

2
Last updated at Posted at 2025-10-06

みなさん、こんにちは!

前回作成したAPIは、/api/helloにアクセスすると決まったメッセージを返すだけでしたが、実際のWebサービスはもっと複雑です。
ユーザーの入力に応じてデータを取得したり、新しいデータをサーバーに送信したりする必要があります。

今回は、前回作ったReactアプリ(クライアント)とNode.jsサーバー(API)を連携させ、「データの取得(GET)」と「データの新規作成(POST)」という、2つの操作をやってみようと思います。

記事のゴール

  • ReactNode.js間で実際にデータをやり取りする
  • URLパラメータを使って、特定のデータを取得するGETリクエストを学ぶ
  • クライアントからサーバーにデータを送信するPOSTリクエストを学ぶ
  • クロスオリジン通信(CORS)という、連携に必須の知識を学ぶ

1. サーバー側の準備:Expressで2つのAPIを作る

前回作成したmy-api-serverフォルダのserver.jsを編集し、機能を追加します。今回は、シンプルな「タスクリスト」のデータを使います。

1.1. Express-CORSの導入

ReactとNode.jsは、デフォルトではセキュリティ上の理由で通信できません。
これは CORS(Cross-Origin Resource Sharing) という仕組みによるものです。これを許可するために、corsというライブラリをインストールします。

ターミナルで、my-api-serverフォルダに移動して実行してください。

npm install cors

1.2. サーバーコードの修正

server.jsの中身をすべて以下のコードに書き換えてください。

// server.js
const express = require('express');
const cors = require('cors'); // ① corsをインポート
const app = express();
const port = 3000;

// ダミーデータ(タスクリスト)
let tasks = [
  { id: 1, title: 'Node.jsの勉強', completed: false },
  { id: 2, title: 'Reactの記事を読む', completed: false },
  { id: 3, title: '休憩する', completed: true }
];
let nextId = 4; // 次に作成するタスクのID

// ミドルウェアの設定
app.use(cors()); // ② 全てのオリジンからのアクセスを許可
app.use(express.json()); // ③ クライアントから送られてきたJSONデータを受け取るための設定

// --- APIエンドポイントの定義 ---

// 1. 全タスクを取得するAPI (GET /api/tasks)
app.get('/api/tasks', (req, res) => {
  // すべてのタスクデータをクライアントに返す
  res.json(tasks);
});

// 2. 新しいタスクを追加するAPI (POST /api/tasks)
app.post('/api/tasks', (req, res) => {
  // ④ クライアントから送られてきたデータ(リクエストボディ)を取得
  const newTaskTitle = req.body.title;

  if (!newTaskTitle) {
    return res.status(400).json({ message: 'タスクのタイトルが必要です' });
  }

  // 新しいタスクオブジェクトを作成
  const newTask = {
    id: nextId++,
    title: newTaskTitle,
    completed: false
  };

  // サーバー側のデータに追加
  tasks.push(newTask);

  // クライアントに、作成された新しいタスク情報を返す
  res.status(201).json(newTask);
});

// サーバーを起動します
app.listen(port, () => {
  console.log(`サーバーが http://localhost:${port} で起動しました`);
});

【コードの解説】

  • app.use(cors()): これにより、Reactが動く別オリジン(例:http://localhost:5173)から、Node.jsサーバー(http://localhost:3000)へアクセスできるようになります。
  • app.use(express.json()): クライアントから送られてくるPOSTリクエストのボディに含まれるJSONデータを、JavaScriptのオブジェクトとして受け取れるようにする設定です。
  • app.get('/api/tasks', ...): タスク一覧を返す、シンプルなGETリクエストのエンドポイントです。
  • app.post('/api/tasks', ...): クライアントからのPOSTリクエストを受け付け、req.body.titleで新しいタスクのタイトルを取得し、サーバー側のデータ(tasks配列)に追加しています。

サーバーを再起動してください。

node server.js

2. クライアント側の準備:Reactでデータ送受信

次に、前回作成したReactアプリ(my-react-app)のコードを修正し、Node.js APIと連携させます。

2.1. Reactコードの修正

my-react-appフォルダのsrc/App.jsxの中身をすべて以下のコードに書き換えてください。

// src/App.jsx
import React, { useState, useEffect } from 'react';
import './App.css';

// APIのエンドポイントURL
const API_URL = 'http://localhost:3000/api/tasks';

function App() {
  // タスク一覧を管理するステート
  const [tasks, setTasks] = useState([]);
  // 新規タスクの入力値を管理するステート
  const [newTaskTitle, setNewTaskTitle] = useState('');
  // ローディングとエラー
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);

  // --- 1. GETリクエスト(タスク一覧の取得) ---
  const fetchTasks = async () => {
    setLoading(true);
    setError(null);
    try {
      const response = await fetch(API_URL); // APIにリクエストを送信
      if (!response.ok) {
        throw new Error(`HTTPエラー! ステータス: ${response.status}`);
      }
      const data = await response.json(); // JSON形式でデータを受け取る
      setTasks(data); // ステートを更新
    } catch (err) {
      setError('タスクの取得に失敗しました。');
      console.error(err);
    } finally {
      setLoading(false);
    }
  };

  // コンポーネントが最初に表示されたときにタスクを取得
  // 今回はuseEffectを使って自動でデータを取得します
  useEffect(() => {
    fetchTasks();
  }, []); // []が空なので、初回レンダリング時のみ実行されます

  // --- 2. POSTリクエスト(タスクの新規作成) ---
  const handleAddTask = async () => {
    if (!newTaskTitle.trim()) return; // 入力がない場合は何もしない

    try {
      const response = await fetch(API_URL, {
        method: 'POST', // HTTPメソッドをPOSTに指定
        headers: {
          'Content-Type': 'application/json', // 送信するデータがJSONであることを指定
        },
        // サーバーに送るデータ(JSON形式に変換)
        body: JSON.stringify({ title: newTaskTitle }), 
      });

      if (!response.ok) {
        throw new Error('タスクの作成に失敗しました。');
      }

      const newTask = await response.json(); // サーバーが返した新しいタスク情報を受け取る
      
      // 既存のタスクリストに新しく作成されたタスクを追加
      setTasks([...tasks, newTask]);
      setNewTaskTitle(''); // 入力フォームをクリア

    } catch (err) {
      setError(err.message);
      console.error(err);
    }
  };

  return (
    <div className="App">
      <h1>My Task App</h1>
      
      {/* エラー表示 */}
      {error && <p style={{ color: 'red' }}>{error}</p>}

      {/* タスク新規作成フォーム (POST) */}
      <div className="task-form">
        <input
          type="text"
          value={newTaskTitle}
          onChange={(e) => setNewTaskTitle(e.target.value)}
          placeholder="新しいタスクを入力"
        />
        <button onClick={handleAddTask}>タスクを追加 (POST)</button>
      </div>
      <hr />

      {/* タスク一覧表示 (GETの結果) */}
      <h2>タスク一覧</h2>
      {loading ? (
        <p>タスクを読み込み中...</p>
      ) : (
        <ul>
          {tasks.map(task => (
            <li key={task.id} style={{ textDecoration: task.completed ? 'line-through' : 'none' }}>
              [{task.id}] {task.title}
            </li>
          ))}
        </ul>
      )}
    </div>
  );
}

export default App;

【コードの解説】

  • useEffectの復活: useEffectを使い、コンポーネントが**最初に表示された時([]が空)**に自動でfetchTasksを呼び出すようにしました。
  • async/await: fetchresponse.json()は非同期処理ですが、then()を繋げる代わりにasyncawaitを使うことで、同期的なコードのように分かりやすく書けるようになります。
  • GETリクエスト: fetch(API_URL)だけで、サーバーからタスク一覧を取得できます。
  • POSTリクエスト:
    • method: 'POST'を指定し、リクエストの種類を伝えます。
    • headers: サーバーに「JSON形式でデータを送るよ」と伝えます。
    • body: JSON.stringify(...): 送りたいJavaScriptオブジェクトを、APIが理解できるJSON文字列に変換して送ります。

2.2. アプリの確認

ターミナルが2つ必要です。

  1. ターミナル1(Node.jsサーバー): my-api-serverフォルダでnode server.jsを実行し、サーバーを起動し続けてください。
  2. ターミナル2(Reactクライアント): my-react-appフォルダでnpm run devを実行し、Reactアプリを起動してください。

ブラウザで確認すると、自動でタスク一覧が表示され、新しいタスクを入力してボタンを押すと、リストがリアルタイムで更新されるはずです。

これで、「フロントエンド(React)」と「バックエンド(Node.js)」が連携するアプリケーションを作成することができました!


3. まとめと次のステップ

今回は、Web開発で最も重要なスキルの一つであるクライアント・サーバー間のデータ送受信をマスターしました。

  • GET: サーバーからデータを取得する
  • POST: クライアントからサーバーへデータを送信する(新規作成)
  • CORS: 異なるサーバー間での通信を可能にするための設定

この連携こそが、現代のあらゆるWebサービスの基盤です。

次回は、サーバー側のタスクデータ(tasks配列)をファイルに保存するなど、より実用的な機能を加えていきます。
今回もお疲れ様でした!次回も頑張ってこー!

おまけ

くすりの窓口では、現在インターンや中途採用を募集しています。
気になる方は以下のリンクよりご確認ください。

2
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
2
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?