任意の時間内にイベントがなければ1度だけアクションを発火

React
スポンサーリンク
language

この記事ではユーザーがイベントを起こしてから、一定の時間新たにイベントがなければ任意のアクションを発火させる方法をご紹介します。

使用用途としてはテキストフォーム入力後1.5秒後に値を送信、またはバリデーションを想定しています。
この用途では要件を満たす必要があります。

  • ユーザーがフォーム入力中はアクションを発火させない
  • フォーム入力後一定時間内に新たにイベントがなければ、アクションを一度だけ発火
スポンサーリンク

デモ

サンプルコード

このサンプルコードはテキストフォームを入力中はアラートがでなく、入力後2秒間新たにテキストの入力がなかったら、アラートがでます。

import React from 'react';

export default function TextInput(props) {
  const [timerId, setTimerId] = React.useState(null);

  const debounce = (fn, bufferInterval = 3000) => {
    return () => {
      clearTimeout(timerId);
      let timer = setTimeout(() => {
        fn();
      }, bufferInterval);
      setTimerId(timer);
    };
  };

  const handleChange = (e) => {
    // 2秒間新たに入力がなければアラートを発火
    debounce(() => {
      alert('アクション開始');
    }, 2000)();
  };

  return (
    <div>
      <input type="text" onChange={(e) => handleChange(e)} />
    </div>
  );
}

サンプルコードの解説

以下の要件を満たすコードの部分を解説をします。

  • ユーザーがフォーム入力中はアクションを発火させない
  • フォーム入力後一定時間内に新たにイベントがなければ、アクションを一度だけ発火

ユーザーがフォーム入力中はアクションを発火させない

ユーザーがテキストフォームを入力する毎にdebounce関数が実行されます。

前回のイベントのアクションを発火させない(フォーム入力中)ために、clearTimeout(timerId)でsetTimeout()でセットしたタイマーを解除しています。

WindowOrWorkerGlobalScope.clearTimeout() - Web API | MDN
clearTimeout() は WindowOrWorkerGlobalScope ミックスインのメソッドで、以前の setTimeout() の呼び出しによって以前に確立されたタイムアウトを解除します。
const [timerId, setTimerId] = React.useState(null);

const debounce = (fn, bufferInterval = 3000) => {
  return () => {
    clearTimeout(timerId); // 前回のタイマーを解除
    let timer = setTimeout(() => {
      fn();
    }, bufferInterval);
    setTimerId(timer);
  };
};

フォーム入力後一定時間内に新たにイベントがなければ、アクションを一度だけ発火

前回のイベントのアクションのタイマーを解除後、新たに一定時間後にアクションを発火するようにタイマーをセットします。

ユーザーが新たにイベントを起こさなければ(フォームを入力しなければ)、最後にセットしたタイマーが一定時間後に実行されてアクションが発火します。

つまり、一定時間内に起きたイベントのアクションはすべて解除されるので、最後に起きたイベントのアクションのみ実行されます。

const [timerId, setTimerId] = React.useState(null);

const debounce = (fn, bufferInterval = 3000) => {
  return () => {
    clearTimeout(timerId); // 前回のタイマーを解除
    let timer = setTimeout(() => { // 新たにタイマーをセット
      fn();
    }, bufferInterval);
    setTimerId(timer); // 今回のタイマーのタイマーIDをセット
  };
};

まとめ

今回のような一定時間内にイベントが無ければ、アクションを起こすために肝になってくるのが、

  • setTimeout()
  • timer id
  • clearTimeout()

です。

これらをうまく使って任意のタイミングでアクションを起こすことができます。

import React from 'react';

export default function TextInput(props) {
  const [timerId, setTimerId] = React.useState(null);

  const debounce = (fn, bufferInterval = 3000) => {
    return () => {
      clearTimeout(timerId); // 前回のタイマーを解除
      let timer = setTimeout(() => { // 新たにタイマーをセット
        fn();
      }, bufferInterval);
      setTimerId(timer); // 今回のタイマーのタイマーIDをセット
    };
  };

  const handleChange = (e) => {
    // 2秒間新たに入力がなければアラートを発火
    debounce(() => {
      alert('アクション開始');
    }, 2000)();
  };

  return (
    <div>
      <input type="text" onChange={(e) => handleChange(e)} />
    </div>
  );
}

この記事でわからないコードなどがあれば、書籍で勉強するのがおすすめです。
プログラミングの技術の移り変わりは早いので最新版の書籍を購入することをお勧めします。
中古本を買って勉強したけど、今は使われない技術だったということはよくあります。

javascript・Reactでおすすめの書籍をご紹介します。

りーほー
りーほー

JavaScriptを基礎からしっかり学びたい方におすすめ!

りーほー
りーほー

JavaScriptを基礎から応用までガッツリ学びたい方におすすめ!

りーほー
りーほー

Reactの概念や仕組みを把握し、開発で使えるReactを学びたい方にオススメ!

タイトルとURLをコピーしました