Yanonoblog!

こつこつと

Reactにおける多重クリック対策について

はじめに

本記事では、多重クリックによって意図しない処理の重複実行を回避する方法についてまとめています。

Reactでは何も考えずに実装するとボタン操作などで発生したイベントが複数回実行され不要なリクエストが発生する問題が発生します。

多重クリック問題について

ユーザーインターフェースにおいて、ボタンの多重クリックは予期せぬバグや、重複したリクエスト送信を引き起こす可能性があります。

最初のクリック後、追加のクリックを無効にする仕組みを実装する必要があります。

useStateを利用した多重クリック防止

useStateを利用してボタンの状態を管理し、クリックを無効にする例です

import React, { useState } from 'react';

const ButtonComponent = () => {
  const [isClicked, setIsClicked] = useState(false);

  const handleClick = async () => {
    setIsClicked(true);
    // 何らかの処理(API呼び出し等)
    setIsClicked(false);
  };

  return (
    <button disabled={isClicked} onClick={handleClick}>
      Submit
    </button>
  );
};

useStateのデメリット

useStateを使うの方法はシンプルでわかりやすいですが、いくつかデメリットもあります。

レンダリングのコスト

setIsClickedがコールされる度にコンポーネントが再レンダリングされます。

非同期処理の複雑性

async/awaitが使われる非同期処理では、setIsClickedが完了するまで待ってから次の処理を行う必要があります。

これが複雑な処理フローを生む可能性があります。

これらのデメリットを解決する方法として、Reactのrefを利用するアプローチがあります。

useRefを利用した多重クリック防止

refは通常、DOM要素への参照を保持するために用いますが、連打対策として操作フラグを保持する用途にも使えます。

import React, { useRef } from 'react';

const ButtonComponent = () => {
  const isClickedRef = useRef(false);

  const handleClick = () => {
    if (isClickedRef.current) {
      return;
    }
    isClickedRef.current = true;
    // 何らかの処理
    isClickedRef.current = false;
  };

  return (
    <button onClick={handleClick}>
      Submit
    </button>
  );
};

useRefを利用したアプローチのメリット

レンダリングコストの削減

useRefはコンポーネントの再レンダリングをトリガーしないため、無駄な描画を抑制します。

シンプルなコードフロー

非同期処理を含むロジックでも状態管理をシンプルに保てます。

注意点

useRefの値が更新されてもコンポーネントは再レンダリングされないため、UIの更新(ボタンの無効化等)が必要な場合は適切な状態管理手法を併用しましょう。

例えば処理完了後、モーダルを閉じる際にフラグを更新するなど

useEffect(() => {
  if (!open) {
    disabledFlagRef.current = false;
  }
}, [open])

まとめ

多重クリック防止は、重複したイベント処理やリクエストの発行を防ぎ、意図しないバグを防ぐ重要な実装です。

  • **useState**を利用した方法はシンプルですが、再レンダリングや非同期処理の管理にコストがかかります。
  • useRefを利用することで、再レンダリングを減らし、非同期処理のコードをシンプルに保つことが可能です。
  • おしまい

    コメント

    本記事の内容は以上になります!


    プログラミングスクールのご紹介 (卒業生より)

    お世話になったプログラミングスクールであるRUNTEQです♪

    https://runteq.jp/r/ohtFwbjW

    こちらのリンクを経由すると1万円引きになります。

    RUNTEQを通じて開発学習の末、受託開発企業をご紹介いただき、現在も双方とご縁があります。

    もし、興味がありましたらお気軽にコメントか、TwitterのDMでお声掛けください。

    https://twitter.com/outputky