はじめに
Next.js(React)と FastAPI を連携したアプリケーションで、ユーザーが日記を投稿すると、AI(さぶちゃん)からの応援メッセージが返ってくる機能を実装しています。
本記事では、返答内容を「さぶちゃんからの熱いエール」欄に画面表示する方法を紹介します。
書こうと思ったきっかけ
受講しているITスクールのハッカソンの開発の一環で、日記投稿後の返答メッセージを見せる仕組みを作ろうとした際に、応答の扱いと表示形式の工夫が必要だったため、記録としてまとめました。
実際の画面(開発中)
実際の画面(一旦、完成画面)
内容
以下は実際に使用している SabutyanMode
コンポーネントの抜粋コードです。応援メッセージの表示に関係する部分を中心に紹介します。
状態管理
const [diaryMessage, setDiaryMessage] = useState("");
const [cheerMessage, setCheerMessage] = useState("");
ユーザーが入力した日記(diaryMessage
)と、APIからの応答メッセージ(cheerMessage
)を別々の状態で管理しています。
応援メッセージの取得処理
const handleEnergy = async () => {
if (!sessionId) {
alert("セッションIDが見つかりません");
return;
}
try {
const payload = {
session_id: Number(sessionId),
is_user: true,
content: diaryMessage,
};
const res = await fetch(`http://localhost:8000/api/sessions/${sessionId}/messages`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(payload),
});
if (!res.ok) throw new Error("送信に失敗しました");
const result = await res.json();
setCheerMessage(result.content || "さぶちゃんから応援が届きました!");
} catch (error) {
console.error("エラー:", error);
alert("エラーが発生しました");
}
};
API のレスポンスから result.content
を取得し、それを cheerMessage
にセットしています。
応援メッセージの表示エリア
<div className="w-full h-32 border border-gray-300 rounded-md p-3 bg-[#fffaf0] whitespace-pre-wrap overflow-y-auto">
{cheerMessage || "ここにさぶちゃんの応援が表示されます"}
</div>
この表示専用 div
によって、API から受け取った応援メッセージがリアルタイムに画面に表示される仕組みとなっています。
起きていた問題
- 日記欄と応援メッセージ欄に同じ状態変数を使っていたため、文字が連動していた
- 応援メッセージを表示させたいが、textarea ではユーザーが編集できてしまう
修正内容
1. 状態管理を分離
const [diaryMessage, setDiaryMessage] = useState("");
const [cheerMessage, setCheerMessage] = useState("");
2. FastAPI 応答を cheerMessage にセット
const result = await res.json();
setCheerMessage(result.content || "さぶちゃんから応援が届きました!");
3. 表示専用のエール欄を div に変更
<div className="w-full h-32 border border-gray-300 rounded-md p-3 bg-[#fffaf0] whitespace-pre-wrap overflow-y-auto">
{cheerMessage || "ここにさぶちゃんの応援が表示されます"}
</div>
- textarea を div に変更し、ユーザーが編集できないように
-
whitespace-pre-wrap
によって改行も反映
まとめ
フォームで状態変数を共通化すると文字が連動してしまうため、用途ごとに状態を分ける必要があります。
また、表示専用の応答欄には div
を用いて、ユーザーが内容を編集できないようにすることが重要です。
これにより、ユーザーが入力した日記に対して、さぶちゃんからの応援を自然な形で表示できるようになりました...!