データ追加(Create)
app/components/CreatDog.js
"use client";
import { useState } from "react";
export default function CreateDog(props) {
const [newDog, setNewDog] = useState({ name: "", age: 0 });
const addDog = async () => {
const newEntry = { name: newDog.name, age: newDog.age };
const response = await fetch("http://localhost:3001/dogs", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(newEntry)
});
if (response.ok) {
const addedDog = await response.json(); // `json-server` が追加したデータを返す
props.setDogs([...props.dogs, addedDog]);
setNewDog({ name: "", age: 0 });
}
};
return (
<div>
<h2>🐕 新しい犬を追加</h2>
<input
type="text"
placeholder="名前"
value={newDog.name}
onChange={(e) => setNewDog({ ...newDog, name: e.target.value })}
/>
<input
type="number"
placeholder="年齢"
value={newDog.age}
onChange={(e) => setNewDog({ ...newDog, age: Number(e.target.value) })}
/>
<button onClick={addDog}>追加</button>
</div>
);
}

コード解説
const [newDog, setNewDog] = useState({ name: "", age: 0 });
入力フォーム用のstateを設定します。
addDog(API通信)処理
「追加」ボタンをクリックしたときのイベントハンドラー「addDog」によるAPI通信の処理を見ていきます。
const addDog = async () => {
const newEntry = { name: newDog.name, age: newDog.age };
const response = await fetch("http://localhost:3001/dogs", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(newEntry)
});
if (response.ok) {
const addedDog = await response.json();
props.setDogs([...props.dogs, addedDog]);
setNewDog({ name: "", age: 0 });
}
};
1行ずつ説明していきます。
const addDog = async () => {
✅ これは関数の定義
👉 const addDog は 関数を変数 addDog に代入している
👉 async () => は 「この関数は非同期処理を行う」 という宣言
💡 「非同期処理って何?」
→ サーバーと通信するとき、データが返ってくるまで待つ必要がある
→ その間に他の処理を進められるのが「非同期」
→ この関数は await を使うために async をつける

const newEntry = { name: newDog.name, age: newDog.age };
✅ 新しい犬のデータをオブジェクトで作る
👉 {} は オブジェクト(データのまとまり)を作る記号
👉 name: newDog.name は、newDog.name の値を name というキーに入れる
👉 age: newDog.age も同じ
💡 「newDog.name って何?」
→ これは React の useState で管理されている newDog の name の値
→ つまり newDog に入力したnameとageを newEntry に入れてる
const response = await fetch("http://localhost:3001/dogs", {
✅ サーバー(json-server)にデータを送る
👉 fetch("URL") は 指定した URL にデータを送ったり受け取ったりする関数
👉 await をつけることで、データが返ってくるまで待つ
💡 「await をつけないとどうなる?」
→ データを待たずに次の処理が進んで、値が undefined になったりバグる
method: "POST",
✅ POST メソッドを使う
👉 HTTP には 4つの基本的なメソッド(動作)がある
| メソッド | 何をする? |
|---|---|
| GET | データを取得(例:犬の一覧をもらう) |
| POST | データを追加(例:新しい犬を登録する) |
| PUT | データを更新(例:犬の年齢を変更する) |
| DELETE | データを削除(例:犬をリストから消す) |
💡 POST だから、新しい犬のデータを送る処理になる
headers: { "Content-Type": "application/json" },
✅ 「このデータは JSON 形式だよ!」とサーバーに伝える
👉 headers は、サーバーに送るデータの種類を指定する部分
👉 "Content-Type": "application/json" は 「送るデータは JSON 形式」と宣言する
body: JSON.stringify(newEntry)
✅ データを JSON に変換して送る
👉 JSON.stringify(データ) は、JavaScript のオブジェクトを JSON 文字列に変換する関数
if (response.ok) {
✅ サーバーが「成功!」と返したら実行
👉 response.ok は、通信が成功 (200 番台のステータス) だったら true になる
👉 もし false だったら、何かエラーが起きたということ
💡 response.ok ってどういう意味?
→ サーバーが「リクエスト成功!」と返したら true になる
→ false の場合はエラー(例:404 Not Found や 500 Server Error)
const addedDog = await response.json();
✅ サーバーから返ってきたデータを JSON に変換
👉 response.json() は、サーバーのレスポンスを JSON 形式のデータに変換する関数
👉 await をつけることで、データが変換されるまで待つ
💡 「なぜ response.json() が必要?」
→ サーバーから返ってくるデータは JSON 形式の文字列だから、そのままじゃ使えない
→ だから response.json() で JavaScript のオブジェクトに変換する
props.setDogs([...props.dogs, addedDog]);
✅ React の state を更新して、新しい犬を追加
👉 props.setDogs() は、親コンポーネントの dogs を更新する関数
👉 [...props.dogs, addedDog] は、現在の dogs 配列に addedDog を追加する
💡 なぜ ...props.dogs (スプレッド構文)を使うの?
→ React の state(props.dogs)は、直接変更できない
→ だから、新しい配列 [...] を作って、更新する
setNewDog({ name: "", age: 0 });
✅ 入力フォームをリセット!
👉 setNewDog({ name: "", age: 0 }) は、新しい犬の情報を 空にする!
👉 次に入力するときに、前回のデータが残らないようにする!
💡 「setNewDog とは?」
→ useState で管理している newDog を更新する関数!
→ フォームの中身をリセットするために使う!
🐵 addDog の処理の流れ
1️⃣ newEntry を作る(新しい犬の情報)
2️⃣ fetch でサーバーにデータを送る(POST リクエスト)
3️⃣ サーバーが処理して response を返す
4️⃣ response.ok なら、データを JSON に変換
5️⃣ props.setDogs([...props.dogs, addedDog]) で state を更新
6️⃣ setNewDog({ name: "", age: 0 }) でフォームをリセット
入力フォームで入力された情報をサーバーに送ってデータベースを更新し、通信がOKであれば、ページで表示されている一覧の内容も更新するという流れの処理です。
responseでサーバーから返ってくるデータの内容は実際はバックエンド側のアプリでPOSTに対して何をreturnするかの記述に依存します。今回は、
👉 json-server で POST リクエストを送ると、デフォルトで 送られたデータに id を追加して返す仕様に準じています。
JSX
return (
<div>
<h2>🐕 新しい犬を追加</h2>
<input
type="text"
placeholder="名前"
value={newDog.name}
onChange={(e) => setNewDog({ ...newDog, name: e.target.value })}
/>
<input
type="number"
placeholder="年齢"
value={newDog.age}
onChange={(e) => setNewDog({ ...newDog, age: Number(e.target.value) })}
/>
<button onClick={addDog}>追加</button>
</div>
);
inputタグの入力フォームでそれぞれnewDogのnameとageをsetNewDog更新用関数を使って更新しています。ここでも、stateの値そのものを変更はできないので、スプレッド構文を使ってそれぞれのキーの値を更新する記述をしています。
onChange={(e) => setNewDog({ ...newDog, name: e.target.value })}
onChange={(e) => setNewDog({ ...newDog, age: Number(e.target.value) })}
「age」を更新するinputタグでは念の為Number()を使って入力された値を数値に変換しています。
全体体に少し複雑に見えますが、すべてを理解するというよりは「書き方を覚える」というスタンスでOKです。
