REACT

useThrottledCallback Hook

A custom React Hook for throttling functions/callbacks with TypeScript support

ReactHooksThrottlePerformanceCallbacks

Code

import { useCallback, useRef } from 'react';

function useThrottledCallback<T __TOKEN_17__ (...args: any[]) => any>(
  callback: T,
  delay = 500,
  leading = true,
  trailing = true
): T {
  const timeoutRef = useRef<NodeJS.Timeout | null>(null);
  const lastExecRef = useRef<number>(0);
  const callbackRef = useRef(callback);
  const argsRef = useRef<Parameters<T>>([]);

  // Update callback ref on each render
  callbackRef.current = callback;

  const throttledCallback = useCallback((...args: Parameters<T>) => {
    argsRef.current = args;
    const now = Date.now();
    const elapsed = now - lastExecRef.current;

    const execute = () => {
      lastExecRef.current = now;
      callbackRef.current(...argsRef.current);
    };

    // Leading execution
    __TOKEN_26__ (leading && elapsed >= delay) {
      execute();
    }
    // Trailing execution
    else __TOKEN_28__ (trailing && !timeoutRef.current) {
      timeoutRef.current = setTimeout(() => {
        execute();
        timeoutRef.current = null;
      }, delay - elapsed);
    }
  }, [delay, leading, trailing]) as T;

  // Cancel throttle
  const cancel = useCallback(() => {
    __TOKEN_30__ (timeoutRef.current) {
      clearTimeout(timeoutRef.current);
      timeoutRef.current = null;
    }
  }, []);

  __TOKEN_4__
  (throttledCallback as any).cancel = cancel;

  return throttledCallback;
}

// Usage example
// const handleScroll = useThrottledCallback(() => {
//   console.log('Scroll position:', window.scrollY);
// }, 200);

// useEffect(() => {
//   window.addEventListener('scroll', handleScroll, { passive: true });
//   return () => window.removeEventListener('scroll', handleScroll);
// }, [handleScroll]);