この記事ではユーザーがイベントを起こしてから、一定の時間新たにイベントがなければ任意のアクションを発火させる方法をご紹介します。
使用用途としてはテキストフォーム入力後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()でセットしたタイマーを解除しています。
https://developer.mozilla.org/ja/docs/Web/API/WindowOrWorkerGlobalScope/clearTimeout
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を基礎からしっかり学びたい方におすすめ!
JavaScriptを基礎から応用までガッツリ学びたい方におすすめ!
Reactの概念や仕組みを把握し、開発で使えるReactを学びたい方にオススメ!
コメント