typescriptintermediate

useThrottle Hook for Rate Limiting

Throttle rapidly-firing values like scroll or resize events with a configurable delay hook.

typescript
import { useEffect, useRef, useState } from 'react';

function useThrottle<T>(value: T, delay: number): T {
  const [throttled, setThrottled] = useState(value);
  const lastExecuted = useRef(Date.now());

  useEffect(() => {
    const elapsed = Date.now() - lastExecuted.current;

    if (elapsed >= delay) {
      setThrottled(value);
      lastExecuted.current = Date.now();
    } else {
      const timer = setTimeout(() => {
        setThrottled(value);
        lastExecuted.current = Date.now();
      }, delay - elapsed);
      return () => clearTimeout(timer);
    }
  }, [value, delay]);

  return throttled;
}

// Usage Example
function ScrollTracker() {
  const [scrollY, setScrollY] = useState(0);
  const throttledY = useThrottle(scrollY, 200);

  useEffect(() => {
    const onScroll = () => setScrollY(window.scrollY);
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);

  return (
    <div className="fixed top-4 right-4 bg-black/80 text-white px-3 py-1 rounded">
      <p>Raw: {scrollY}px</p>
      <p>Throttled: {throttledY}px</p>
    </div>
  );
}

export { useThrottle, ScrollTracker };

Use Cases

  • Scroll position tracking
  • Resize event handling
  • Search-as-you-type rate limiting

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.