@thibault.sh/hooks
Version: 
A comprehensive collection of React hooks for browser storage, UI interactions, and more
1 lines • 2.91 kB
Source Map (JSON)
{"version":3,"sources":["../src/hooks/useThrottle.ts"],"names":["useThrottle","value","interval","throttledValue","setThrottledValue","useState","lastUpdated","useRef","useEffect","now","timeSinceLastUpdate","timeoutId"],"mappings":"8CAsCO,SAASA,CAAeC,CAAAA,CAAAA,CAAUC,EAAqB,CAC5D,GAAM,CAACC,CAAAA,CAAgBC,CAAiB,CAAIC,CAAAA,QAAAA,CAAYJ,CAAK,CAAA,CACvDK,EAAcC,MAAe,CAAA,IAAA,CAAK,GAAI,EAAC,EAE7C,OAAAC,SAAAA,CAAU,IAAM,CACd,IAAMC,CAAM,CAAA,IAAA,CAAK,KACXC,CAAAA,CAAAA,CAAsBD,EAAMH,CAAY,CAAA,OAAA,CAE9C,GAAII,CAAAA,EAAuBR,EACzBE,CAAkBH,CAAAA,CAAK,CACvBK,CAAAA,CAAAA,CAAY,QAAUG,CACjB,CAAA,KAAA,CACL,IAAME,CAAAA,CAAY,WAAW,IAAM,CACjCP,CAAkBH,CAAAA,CAAK,EACvBK,CAAY,CAAA,OAAA,CAAU,IAAK,CAAA,GAAA,GAC7B,CAAGJ,CAAAA,CAAAA,CAAWQ,CAAmB,CAAA,CAEjC,OAAO,IAAM,YAAA,CAAaC,CAAS,CACrC,CACF,CAAG,CAAA,CAACV,EAAOC,CAAQ,CAAC,EAEbC,CACT","file":"useThrottle.mjs","sourcesContent":["import { useState, useEffect, useRef } from \"react\";\n\n/**\n * Hook that throttles a value, limiting how often it can update.\n *\n * Unlike debouncing which delays execution until after a quiet period, throttling\n * ensures the value updates at most once per specified interval, making it ideal\n * for scroll events, resize handlers, or any high-frequency updates.\n *\n * @template T - The type of the value being throttled\n * @param value - The value to throttle\n * @param interval - The minimum time interval between updates in milliseconds\n *\n * @returns The throttled value that updates at most once per interval\n *\n * @example\n * ```tsx\n * function ScrollTracker() {\n *   const [scrollY, setScrollY] = useState(0);\n *   const throttledScrollY = useThrottle(scrollY, 100);\n *\n *   useEffect(() => {\n *     const handleScroll = () => setScrollY(window.scrollY);\n *     window.addEventListener('scroll', handleScroll);\n *     return () => window.removeEventListener('scroll', handleScroll);\n *   }, []);\n *\n *   useEffect(() => {\n *     // This will only run at most once every 100ms\n *     console.log('Throttled scroll position:', throttledScrollY);\n *   }, [throttledScrollY]);\n *\n *   return <div>Scroll position: {throttledScrollY}px</div>;\n * }\n * ```\n *\n * @see https://thibault.sh/hooks/use-throttle\n */\nexport function useThrottle<T>(value: T, interval: number): T {\n  const [throttledValue, setThrottledValue] = useState<T>(value);\n  const lastUpdated = useRef<number>(Date.now());\n\n  useEffect(() => {\n    const now = Date.now();\n    const timeSinceLastUpdate = now - lastUpdated.current;\n\n    if (timeSinceLastUpdate >= interval) {\n      setThrottledValue(value);\n      lastUpdated.current = now;\n    } else {\n      const timeoutId = setTimeout(() => {\n        setThrottledValue(value);\n        lastUpdated.current = Date.now();\n      }, interval - timeSinceLastUpdate);\n\n      return () => clearTimeout(timeoutId);\n    }\n  }, [value, interval]);\n\n  return throttledValue;\n}\n"]}