1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【React】ボタンの二重送信を防止するシンプルな方法

Posted at

皆さん、こんにちは。

今回は「【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など)を使ってグローバルな送信状態を管理することもできます。

今日は以上です。

ありがとうございました。
よろしくお願いいたします。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?