皆さん、こんにちは。
今回は「【React】ボタンの二重送信を防止するシンプルな方法」について紹介させていただきます。
はじめに
Reactでフォーム送信やAPIリクエストを伴うボタンを作るとき、**二重送信(ダブルクリック)**の対策はとても重要です。
対策をしないと、意図しない重複処理が走ってしまい、以下のような問題が起こる可能性があります。
重複した注文や登録
サーバーへの過剰リクエスト
ユーザー体験の低下
この記事では、Reactで二重送信を防ぐための基本的な実装パターンを紹介します。
実装例
以下のようなボタンを例に説明します。
✅ 基本的な二重送信防止方法(isLoadingフラグの活用)
import React, { useState } from "react";
const SubmitButton = () => {
const [isLoading, setIsLoading] = useState(false);
const handleClick = async () => {
if (isLoading) return; // 二重送信を防止
setIsLoading(true);
try {
// ここにAPI呼び出しなどの非同期処理を記述
await new Promise((resolve) => setTimeout(resolve, 2000));
alert("送信完了!");
} catch (error) {
console.error("エラー:", error);
} finally {
setIsLoading(false); // 処理が完了したら再びクリック可能に
}
};
return (
<button onClick={handleClick} disabled={isLoading}>
{isLoading ? "送信中..." : "送信"}
</button>
);
};
export default SubmitButton;
解説ポイント
- isLoading という状態フラグを使って、「送信中」かどうかを判定しています。
- 送信処理中 (isLoading: true) はクリックイベントを無視。
- ボタンの disabled 属性を使ってUI上でも無効にしています。
- 処理が終わった後に isLoading を false に戻すことで、再度送信可能になります。
応用:トースト通知やローダー連携も可能
以下のようなライブラリと組み合わせると、よりユーザーフレンドリーな体験が作れます。
- react-toastify:成功・失敗時のトースト通知
- react-spinners:ローディングスピナーの表示
まとめ
Reactで二重送信を防ぐには、isLoading のような状態フラグを活用するのが最も簡単で効果的な方法です。
実際のプロジェクトでも、このパターンは多用されているので、ぜひ取り入れてみてください!
ボタンクリック以外にも、フォームの onSubmit に対して同様のロジックを組み込むことも可能です。
状態管理ライブラリ(ReduxやRecoilなど)を使ってグローバルな送信状態を管理することもできます。
今日は以上です。
ありがとうございました。
よろしくお願いいたします。