はじめに
Claude Codeに「保存ボタンを押したらメモを登録する機能を作って」と頼むと、フォームの送信処理がすぐに実装されます。1回押して確認する分には、ちゃんと1件登録され、動作確認も問題なく通ることが多いです。
ただ、通信が少し遅い環境で試したり、焦って早くボタンを押したりすると、同じ内容のメモが2件、3件と登録されてしまうことがあります。これは実装が間違っているわけではなく、「連続で押されたときにどうするか」という条件が、最初の依頼には含まれていなかっただけです。
本記事では、二重送信が起きる仕組みと、AIに実装を頼むときに伝えておくと防げる観点を、コード例つきで紹介します。
なぜ2回押しただけで2件登録されるのか
保存ボタンを押すと、サーバーにデータを送るリクエストが1回発生します。ボタンを2回押せば、リクエストも単純に2回発生します。
async function handleSave() {
await fetch("/api/memos", {
method: "POST",
body: JSON.stringify({ text: memoText }),
});
}
この処理には、「今リクエストを送信中かどうか」という状態がどこにも記録されていません。ボタンがまだ押せる状態のままなので、1回目のリクエストが終わる前に2回目を押すと、そのまま2回目のリクエストも飛んでいきます。
見た目上は保存が終わって画面が切り替わるので、押した本人は「2回押したこと」に気づきにくいことがあります。気づくのは、後から一覧を見て同じメモが2つ並んでいるのを発見したときです。
送信中はボタンを押せなくする
いちばん基本的な対策は、リクエストが完了するまでボタンを無効化することです。
const [isSaving, setIsSaving] = useState(false);
async function handleSave() {
if (isSaving) return;
setIsSaving(true);
try {
await fetch("/api/memos", {
method: "POST",
body: JSON.stringify({ text: memoText }),
});
} finally {
setIsSaving(false);
}
}
<button onClick={handleSave} disabled={isSaving}>
{isSaving ? "保存中..." : "保存"}
</button>
isSaving が true の間はボタンが押せなくなるので、通信中に連打しても2回目以降のクリックは無視されます。ボタンの表示を「保存中...」に変えておくと、押した本人にも「今処理が進んでいる」ことが伝わります。
クライアント側の対策だけでは足りない場合もある
ボタンの無効化はクリック連打には効きますが、通信が不安定でブラウザが同じリクエストを自動的に再送するケースや、複数タブで同じ画面を開いているケースまでは防げません。
より確実にしたい場合は、サーバー側でも「同じ内容の登録が短時間に連続していないか」をチェックする、あるいはリクエストごとに一意なIDを振って、同じIDのリクエストは2回目以降を無視する、という対策を組み合わせます。ただし、未経験のうちはまず「ボタンを無効化する」というクライアント側の対策から押さえておけば、クリック連打による二重送信への対策としては十分です。
AIに実装を頼むときに伝えておくこと
「保存機能をつけて」とだけ頼むのではなく、「保存中はボタンを押せないようにして、連打しても2回登録されないようにしてください」と、二重送信への対応まで含めて伝えておくと、この手の見落としを事前に防げます。
依頼した後であれば、「このボタンは連打されたとき、リクエストが2回飛びませんか?」と一言確認するだけでも、対策が入っているかどうかをその場で教えてもらえます。
まとめ
- 保存ボタンを2回押すと、単純に2回リクエストが飛んで2件登録される
- 原因は「送信中かどうか」を管理する状態がないこと
-
isSavingのような状態でボタンを無効化するだけで、多くの二重送信は防げる - 「連打されても大丈夫か」を、依頼の時点かレビューの時点で必ず確認する
未経験者向けの講座を運営しています
未経験から Next.js + Supabase + Claude Code で Webアプリを公開するまで を、全20セッションで体系化した教材です。Claude Code を学習パートナーにする CLAUDE.md と学習モード(learner / developer)の設計までセットで含みます。
- ▶ ライブデモ(インストール不要・無料で今すぐ見られます)→ https://trial-web-ayies128s-projects.vercel.app/?ref=qiita
- 教材完全版+月5,500円のメンタリング(全20セッション+チャット質問し放題)→ https://menta.work/plan/20251?ref=qiita
- 無料体験版(git clone して自分の手元で動かす・最初の数セッション分・⭐ Star もよろしくお願いします)→ https://github.com/ayies128/next-ai-camp-trial
- YouTube『AIエンジニア情報局』(AI×開発ニュースを1本5分でキャッチアップできる別運営チャンネル・無料)→ https://www.youtube.com/channel/UC1rXVD9WYsQPQEWZyd-A1KA/?ref=qiita
※ Qiita読者の方には易しすぎる内容なので、初心者の知り合いへの紹介や社内研修の参考としてどうぞ。