Files
archived-linsa/web/shared/hooks/use-throttle-callback.ts
Aslam a440828f8c chore: Enhancement + New Feature (#185)
* wip

* wip page

* chore: style

* wip pages

* wip pages

* chore: toggle

* chore: link

* feat: topic search

* chore: page section

* refactor: apply tailwind class ordering

* fix: handle loggedIn user for guest route

* feat: folder & image schema

* chore: move utils to shared

* refactor: tailwind class ordering

* feat: img ext for editor

* refactor: remove qa

* fix: tanstack start

* fix: wrong import

* chore: use toast

* chore: schema
2024-10-18 21:18:20 +07:00

54 lines
1.4 KiB
TypeScript

import { useCallback, useRef, useEffect } from "react"
type AnyFunction = (...args: any[]) => any
export function useThrottleCallback<T extends AnyFunction>(
callback: T,
deps: React.DependencyList,
delay: number,
): T {
const timeoutRef = useRef<NodeJS.Timeout | null>(null)
const lastCalledRef = useRef<number>(0)
const callbackRef = useRef<T>(callback)
// Update the callback ref whenever the callback changes
useEffect(() => {
callbackRef.current = callback
}, [callback])
useEffect(() => {
// Cleanup function to clear the timeout
return () => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current)
}
}
}, [])
return useCallback(
(...args: Parameters<T>) => {
const now = Date.now()
if (now - lastCalledRef.current >= delay) {
// If enough time has passed, call the function immediately
lastCalledRef.current = now
callbackRef.current(...args)
} else {
// Otherwise, set a timeout to call the function later
if (timeoutRef.current) {
clearTimeout(timeoutRef.current)
}
timeoutRef.current = setTimeout(
() => {
lastCalledRef.current = Date.now()
callbackRef.current(...args)
},
delay - (now - lastCalledRef.current),
)
}
},
[delay, ...deps],
) as T
}