JavaScriptとReactのdebounce解説
JavaScriptとReactにおける「debounce」についての解説
debounceとは?
debounceは、あるイベントが一定時間内に連続して発生した場合に、そのイベントの処理を遅延させる手法です。これにより、頻繁に発生するイベントによるパフォーマンスの低下や、ユーザー体験の悪化を防止することができます。
JavaScriptでのdebounceの実装例
function debounce(func, delay) {
let timeoutId;
return function(...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
func.apply(this, args);
}, delay);
};
}
この関数は、引数として実行したい関数func
と遅延時間delay
を受け取ります。内部では、timeoutId
という変数を使い、前回のタイマーをクリアしてから新しいタイマーを設定します。これにより、連続してイベントが発生した場合でも、最後のイベントのみが処理されるようになります。
Reactにおけるdebounceの活用例
Reactコンポーネント内でdebounceを使う場合、通常はuseEffect
フックを使用します。
import { useEffect, useState } from 'react';
function MyComponent() {
const [inputValue, setInputValue] = useState('');
useEffect(() => {
const debouncedSearch = debounce((value) => {
// 検索処理
console.log('Searching for:', value);
}, 500);
debouncedSearch(inputValue);
return () => {
clearTimeout(debouncedSearch.timeoutId);
};
}, [inputValue]);
return (
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
/>
);
}
この例では、入力フィールドの値が変更されるたびにdebouncedSearch
関数を実行しています。この関数は、500ミリ秒間入力がない場合にのみ検索処理を実行します。これにより、頻繁なタイピングによるパフォーマンスの低下を防ぐことができます。
注意
- Reactの
useMemo
やuseCallback
フックと併用することで、パフォーマンスをさらに最適化することができます。 - debounceの過度の使用は、ユーザーの入力体験を遅らせる可能性があります。適切な遅延時間を設定することが重要です。
function debounce(func, delay) {
let timeoutId;
return function(...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
func.apply(this, args);
}, delay);
};
}
- 内部処理
timeoutId
: タイマーのIDを保持する変数return function(...args)
: debounced関数を返します。clearTimeout(timeoutId)
: 既存のタイマーをクリアします。setTimeout(() => { func.apply(this, args); }, delay)
: 新しいタイマーを設定し、delay
ミリ秒後にfunc
を実行します。
import { useEffect, useState } from 'react';
function MyComponent() {
const [inputValue, setInputValue] = useState('');
useEffect(() => {
const debouncedSearch = debounce((value) => {
// 検索処理
console.log('Searching for:', value);
}, 500);
debouncedSearch(inputValue);
return () => {
clearTimeout(debouncedSearch.timeoutId);
};
}, [inputValue]);
return (
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
/>
);
}
- クリーンアップ関数
- debouncedSearch関数
- 500ミリ秒間入力がない場合にのみ、
console.log
で検索処理をシミュレートします。
- 500ミリ秒間入力がない場合にのみ、
- useEffectフック
ポイント
- 適切な遅延時間を設定することで、ユーザー体験を損なわずにdebounceの効果を発揮できます。
- Reactの
useEffect
フックと組み合わせて、入力フィールドの値変更などに応じた処理を効率的に実行できます。 debounce
は、頻繁に発生するイベントの処理を遅延させることで、パフォーマンスを改善します。
Throttle
Throttleは、一定時間内にイベントが何回発生しても、そのイベントの処理を最初に発生したときと最後に発生したときのみ実行する手法です。debounceとは異なり、一定の間隔で処理を実行する点が特徴です。
実装例
function throttle(func, delay) {
let lastTime = 0;
return function(...args) {
const now = Date.now();
if (now - lastTime >= delay) {
func.apply(this, args);
la stTime = now;
}
};
}
Lodashのdebounce/throttle
LodashはJavaScriptのユーティリティライブラリであり、debounceとthrottleの機能を提供しています。Lodashを使用することで、簡潔なコードでdebounceやthrottleを実装することができます。
import { debounce, throttle } from 'lodash';
const debouncedFunc = debounce(myFunction, 500);
const throttledFunc = throttle(myFunction, 500);
RxJSのdebounceTime/throttleTime
RxJSはリアクティブプログラミングのためのライブラリであり、debounceTimeとthrottleTimeのオペレーターを提供しています。RxJSを使用することで、より宣言的なスタイルでdebounceやthrottleを実装することができます。
import { fromEvent, debounceTime, throttleTime } from 'rxjs';
const inputElement = document.getElementById('myInput');
fromEvent(inputElement, 'input')
.pipe(debounceTime(500))
.subscribe((event) => {
// 検索処理
});
カスタムフック
Reactでは、カスタムフックを使用してdebounceやthrottleのロジックを再利用することができます。カスタムフックは、コンポーネントのロジックを抽出して再利用するための便利な手段です。
import { useState, useEffect } from 'react';
function useDebounce(value, delay) {
const [debouncedValue, setDebouncedValue] = useState(value);
useEffect(() => {
co nst timeoutId = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => clearTimeout(timeoutId);
}, [value, delay]);
return debouncedValue ;
}
javascript reactjs