React 入門
JavaScript コメント掲示板アプリの開発
新規投稿で API に POST
ここでは,新規投稿時に API サーバにも POST メソッドを送信してデータを登録するようにします.まず,ターミナル(またはコマンドプロンプト)から curl
コマンドで POST メソッドを送信する方法を確認します.次の通り,-X POST
でメソッドを指定し,-d
オプションを使ってタイトルや本文の情報を指定します.
% curl -X POST -d "title=API" -d "body=test" http://127.0.0.1:8000/comments/ ⏎
上のコマンドで API サーバに登録した後にブラウザで再読込すると,登録された内容が表示されることを確認します.
では,CommentListPage コンポーネントで新規投稿処理を行っている関数内で,Axios によってデータを送信します.
src/components/CommentListPage.js(抜粋)
const handelCreateFormSubmit = (title, body) => {
const newComments = [...results.results]; // スプレッド構文でコメントの配列だけを取り出す
newComments.unshift({ // unshift で先頭に追加,push では最後に追加
id: Date.now(),
title: title,
body: body,
updated_at: "2024-02-25T15:30:00",
});
const newResults = {
"count": results.count + 1, // コメント数は1増やす
"previous": results.previous,
"next" : results.next,
"results": newComments, // これがコメントの配列
};
setResults(newResults); // 画面を更新
// API に POST でリクエストする
const url = "http://127.0.0.1:8000/comments/";
axios
.post(url, {
title: title,
body: body,
})
.then(res => {
console.log(res.data);
})
.catch(err => {
setResults(results); // 画面を元に戻す(元の配列で更新)
alert("投稿エラー!未入力または文字数超過です.");
});
}
上の画面のとおり,タイトルと本文を入力して投稿すると,15行目で画面が更新された後,API サーバにも登録されます(登録されたかどうかは25行目のとおりブラウザコンソールのログにだけ出力されます.).しかし,タイトルや本文が空の場合や文字数が制限(タイトル最大10文字,本文最大15文字)を超過した場合は,28行目の処理によって画面が投稿前の状態に戻された後,エラー画面が表示されます.なお,文字数の制限は API 側で行っているので,必要に応じて最大文字数を調整してください.
登録後は次のような画面になります.このとき,API へは登録のための POST メソッドを送信しただけで,GET メソッドで最新の状態を取得していないので,3件のコメントが表示されていることにも注意してください.
また,CommentListPage コンポーネントで管理している投稿データには,投稿日時で設定された ID が4行目で設定され,仮の更新日時が7行目で設定されています.一方で,API 側にはデータベースで管理された固有の ID が設定され,実際の更新日時も設定されている状態です.つまり,タイトルと本文は画面の内容とデータベースで等しいですが,ID や更新日時は異なります.
もしも投稿完了時に画面に表示されているコメントの ID や更新日時をデータベースの内容に一致させる必要があるのであれば,上の画面のとおり API への投稿完了後に API から得られた結果を利用するか,GET メソッドで最新データを改めて取得し直すようにするとよいでしょう.GET メソッドで取得し直すためには,URL を引数に指定すると API からデータを取得して画面を更新する処理を行う関数を定義します.その上で POST に成功した後にその関数を実行するとよいでしょう.
src/components/CommentListPage.js(抜粋)
const handleCommentsListChange = (url) => {
axios.get(url)
.then(res => setResults(res.data))
.catch(err => console.log(err.message));
}
...
const handelCreateFormSubmit = (title, body) => {
const newComments = [...results.results]; // スプレッド構文でコメントの配列だけを取り出す
newComments.unshift({ // unshift で先頭に追加,push では最後に追加
id: Date.now(),
title: title,
body: body,
updated_at: "2024-02-25T15:30:00",
});
const newResults = {
"count": results.count + 1, // コメント数は1増やす
"previous": results.previous,
"next" : results.next,
"results": newComments, // これがコメントの配列
};
setResults(newResults); // 画面を更新
// API に POST でリクエストする
const url = "http://127.0.0.1:8000/comments/";
axios
.post(url, {
title: title,
body: body,
})
.then(res => {
// console.log(res.data);
handleCommentsListChange(url);
})
.catch(err => {
setResults(results); // 画面を元に戻す(元の配列で更新)
alert("投稿エラー!未入力または文字数超過です.");
});
}
投稿完了後に GET メソッドを改めて送信するように変更して,もう一度ブラウザから投稿します.
投稿完了後に最新の2件のコメントだけが表示されるようになりました.