やりたいことまとめ
・各投稿に「編集」と「削除」ボタン
・「編集」押したらその投稿のタイトル・内容だけ編集フォーム表示
・「削除」押したらその投稿を削除
import { useState, useEffect } from "react";
const Home = () => {
const [threads, setThreads] = useState([]);
const [editId, setEditId] = useState(null);
const [editTitle, setEditTitle] = useState("");
const [editContent, setEditContent] = useState("");
useEffect(() => {
fetch("http://localhost:8080/app/threads")
.then((res) => res.json())
.then((data) => setThreads(data))
.catch(() => alert("エラー"));
}, []);
// 編集ボタン押したときの処理
const handleEditClick = (thread) => {
setEditId(thread.id);
setEditTitle(thread.title);
setEditContent(thread.content);
};
// 編集を保存する処理
const handleUpdate = (id) => {
fetch(`http://localhost:8080/app/threads/${id}`, {
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
title: editTitle,
content: editContent,
}),
})
.then(() => {
// 更新後に再読み込み
return fetch("http://localhost:8080/app/threads")
.then((res) =>
res.json()
);
})
.then((data) => {
setThreads(data);
setEditId(null); // フォーム閉じる
})
.catch(() => alert("更新エラー"));
};
// 削除処理
const handleDelete = (id) => {
fetch(`http://localhost:8080/app/threads/${id}`, {
method: "DELETE",
})
.then(() => {
setThreads(threads.filter((thread) => thread.id !== id));
})
.catch(() => alert("削除エラー"));
};
return (
<div>
<ul>
{threads.map((thread) => (
<li key={thread.id}>
{editId === thread.id ? (
// 編集フォーム表示
<div>
<input
value={editTitle}
onChange={(e) => setEditTitle(e.target.value)}
/>
<input
value={editContent}
onChange={(e) => setEditContent(e.target.value)}
/>
<button onClick={() => handleUpdate(thread.id)}>保存</button>
<button onClick={() => setEditId(null)}>キャンセル</button>
</div>
) : (
// 通常表示
<div>
<p>タイトル: {thread.title}</p>
<p>内容: {thread.content}</p>
<p>ユーザー名: {thread.name}</p>
<p>時間: {thread.postedat}</p>
<button onClick={() => handleEditClick(thread)}>編集</button>
<button onClick={() => handleDelete(thread.id)}>削除</button>
</div>
)}
</li>
))}
</ul>
</div>
);
};
export default Home;
このコードのポイント
・ 編集ボタン押したら、その投稿だけ入力フォームに切り替え
・ 保存したらPUTで更新、そのあと一覧を再取得
・ 削除ボタン押したらDELETEして、一覧から削除
{
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
title: editTitle,
content: editContent,
}),
}
ここはfetch()でバックエンドにデータを送るときの設定
・method: "PUT"
PUTメソッドでリクエストするって意味。既存データを更新するのはPUT。
・headers: { "Content-Type": "application/json" }
リクエストのデータ形式はJSONですよってサーバーに伝えてる
・body: JSON.stringify({ title: editTitle, content: editContent })
実際にサーバーに送るデータ。JSON形式の文字列に変換して送る必要があるから、JSON.stringify()ってしてる。
const [threads, setThreads] = useState([]);
const [editId, setEditId] = useState(null);
const [editTitle, setEditTitle] = useState("");
const [editContent, setEditContent] = useState("");
これは **ReactのuseState(状態管理)**ってやつ。
ざっくり言うと「画面に表示する値を管理する箱を作ってる」感じ!
① const [threads, setThreads] = useState([]);
スレッドのデータを入れる箱
・threads → 今のデータ
・setThreads → データを更新する関数
・useState([]) → 最初は空の配列
② const [editId, setEditId] = useState(null);
今どの投稿を編集しようとしてるかのIDを入れる箱
・editId → 今編集中の投稿のID(なければnull)
・setEditId → そのIDを更新する用の関数
③ const [editTitle, setEditTitle] = useState("");
編集中のタイトルを一時的に保存する箱
・editTitle → 入力されたタイトル
・setEditTitle → タイトルを更新する用の関数
④ const [editContent, setEditContent] = useState("");
編集中の内容を一時的に保存する箱
・editContent → 入力された内容
・setEditContent → 内容を更新する用の関数
まとめると
threads
スレッドの一覧データ
editId
今編集中の投稿のID
editTitle
編集中のタイトル
editContent
編集中の内容
イメージ
例えば「編集ボタン押したらその投稿のIDを editId にセットして、フォームに今のタイトルと内容をセットして編集できるようにする」って感じの流れにするための準備!
body: JSON.stringify({
title: editTitle,
content: editContent
})
ここは
「APIに送るデータをJSON形式の文字列に変換してセットする」っていう処理。
つまり title: editTitle は
「titleっていう名前で、editTitleっていう変数の中身の値を送るよ」って意味。
名前は自由
例えば、もし
const [editedTitle, setEditedTitle] = useState("")
const [editedContent, setEditedContent] = useState("")
って変数名にしてたら
body: JSON.stringify({
title: editedTitle,
content: editedContent
})
って書けばOK。
要は「キーと値」のセット
・キー → APIに送るときの名前(相手側で決まってるならそれに合わせる)
・値 → こっちのReact側の変数名(自由)
ってこと!