Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | 238x 238x 238x 238x 238x 238x 127x 127x 238x 16x 16x 16x 13x 13x 3x 2x 2x 2x 2x 2x | /**
* useThrottle Hook
*
* Throttles a function to execute at most once per specified interval.
* Useful for high-frequency events like scroll, resize, or touch move.
*
* Uses a ref pattern to ensure the latest callback is always called
* without recreating the throttled function on every render.
*
* @module hooks/useThrottle
* @category Performance
* @korean 쓰로틀 훅
*/
import { useCallback, useRef, useLayoutEffect, useEffect } from 'react';
/**
* Hook to throttle a callback function
*
* @param callback - Function to throttle
* @param delay - Minimum delay between executions in milliseconds
* @returns Throttled function
*
* @example
* ```tsx
* const handleTouchMove = useThrottle((event: TouchEvent) => {
* // Handle touch move
* }, 16); // ~60fps
* ```
*/
export function useThrottle<T extends (...args: never[]) => void>(
callback: T,
delay: number
): T {
const lastRunRef = useRef<number>(0);
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
const callbackRef = useRef(callback);
// Keep callback ref up to date
useLayoutEffect(() => {
callbackRef.current = callback;
});
// Cleanup pending timeout on unmount
useEffect(() => {
return () => {
Iif (timeoutRef.current) {
clearTimeout(timeoutRef.current);
}
};
}, []);
return useCallback(
(...args: Parameters<T>) => {
const now = Date.now();
const timeSinceLastRun = now - lastRunRef.current;
if (timeSinceLastRun >= delay) {
// Execute immediately if enough time has passed
lastRunRef.current = now;
callbackRef.current(...args);
} else if (!timeoutRef.current) {
// Schedule execution for later
const timeUntilNext = delay - timeSinceLastRun;
timeoutRef.current = setTimeout(() => {
lastRunRef.current = Date.now();
timeoutRef.current = null;
callbackRef.current(...args);
}, timeUntilNext);
}
},
[delay]
) as T;
}
export default useThrottle;
|