mirror of
https://github.com/linsa-io/linsa.git
synced 2026-01-12 12:20:23 +01:00
* 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
54 lines
1.4 KiB
TypeScript
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
|
|
}
|