データ追加(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です。
コメント