typescriptintermediate

useScrollPosition Hook

Tracks window scroll position with throttling for performance-sensitive scroll effects.

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

interface ScrollPosition {
  x: number;
  y: number;
}

export function useScrollPosition(throttleMs = 100): ScrollPosition {
  const [position, setPosition] = useState<ScrollPosition>({ x: 0, y: 0 });
  const lastUpdate = useRef(0);

  useEffect(() => {
    const handleScroll = () => {
      const now = Date.now();
      if (now - lastUpdate.current < throttleMs) return;
      lastUpdate.current = now;
      setPosition({ x: window.scrollX, y: window.scrollY });
    };

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

  return position;
}

Use Cases

  • Sticky headers
  • Scroll-based animations

Tags

Related Snippets

Similar patterns you can reuse in the same workflow.