1
0

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 nativeで開発をした際に使用していた連打対策のためのカスタムフックを紹介します。

背景

画面遷移を行うボタンを連打すると同じページが2回開いてしまうなど、連打できることで問題が発生してしまうコンポーネントがいくつかありました。

また、連打対策をする必要のあるコンポーネントが多数存在したので、利用しやすいカスタムフックで作成しました。

実装

useDebounce.ts
import { useRef } from 'react';

export const useDebounce = () => {
  const canPress = useRef<boolean>(true);

  const debounce = (onPress: Function, duration: number = 1000) => {
    setTimeout(() => {
      canPress.current = true;
    }, duration);

    if (canPress.current) {
      canPress.current = false;
      onPress();
    }
  };

  return { debounce };
};

使用例

以下のように、hooksから返されるdebounce()で関数をラップすることで、簡単に連打対策が実現できます。

const Button: FC = () => {
  const { debounce } = useDebounce();

  const handleClick = () => {
    console.log('clicked');
  };

  return (
    <button
      onClick={() => debounce(handleClick)} // 連打しても初回クリックから1秒間は無効
    >
      Click
    </button>
  );
};

debounce(handleClick, 2000)のように、第2引数に任意の秒数(ms単位)を指定することもできます。

解説

簡単な実装ではありますが、一応解説です。

useDebouncecanPressというRefを持っています。初期値はtrueです。

useRefについてわからないって方はぜひ公式のリファレンスをご覧ください!

<button
  onClick={() => debounce(handleClick)}
>

上記のような実装をしたとき、onClickが発火するとsetTimeoutが走ります。

setTimeout(() => {
  canPress.current = true;
}, duration);

durationに設定した時間がたった後(デフォルトでは1000ms=1秒後)、canPress.currentにtrueをセットします。

その後以下のようなコードが続きます。

if (canPress.current) {
  canPress.current = false;
  onPress();
}

canPress.currentがtrueの時、if文の中身を実行しています。
canPress.currentにfalseをセットし、引数のonPressを実行します。

このような実装をすることによって、

  1. 初回ボタンクリック時に引数のonPressを実行しつつcanPress.currentをfalseに。1秒後にcanPress.currentをtrueに戻すタイマーもセット

  2. 1秒経過する前にクリックされると、canPress.currentがfalseであるためif文で弾かれてonPressは実行されない

  3. 1秒経過するとcanPress.currentをtrueに戻すタイマーが作動し、再度クリックでonPressが発火するようになる

という動作が実現できます。

おわりに

最後までお読みいただきありがとうございました!
もっといい方法をご存知の方はコメントで教えてくださると嬉しいです🙇‍♂️

1
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?