|
|
import { useCallback, useRef } from 'react'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export const useDebouncedUpdates = (delay = 16) => { |
|
|
const timeoutRef = useRef(null); |
|
|
const pendingUpdateRef = useRef(null); |
|
|
|
|
|
|
|
|
const debouncedUpdate = useCallback((updateFn) => { |
|
|
|
|
|
pendingUpdateRef.current = updateFn; |
|
|
|
|
|
|
|
|
if (timeoutRef.current) { |
|
|
clearTimeout(timeoutRef.current); |
|
|
} |
|
|
|
|
|
|
|
|
timeoutRef.current = setTimeout(() => { |
|
|
if (pendingUpdateRef.current) { |
|
|
pendingUpdateRef.current(); |
|
|
pendingUpdateRef.current = null; |
|
|
} |
|
|
}, delay); |
|
|
}, [delay]); |
|
|
|
|
|
|
|
|
const flushUpdate = useCallback(() => { |
|
|
if (timeoutRef.current) { |
|
|
clearTimeout(timeoutRef.current); |
|
|
timeoutRef.current = null; |
|
|
} |
|
|
if (pendingUpdateRef.current) { |
|
|
pendingUpdateRef.current(); |
|
|
pendingUpdateRef.current = null; |
|
|
} |
|
|
}, []); |
|
|
|
|
|
|
|
|
const cancelUpdate = useCallback(() => { |
|
|
if (timeoutRef.current) { |
|
|
clearTimeout(timeoutRef.current); |
|
|
timeoutRef.current = null; |
|
|
} |
|
|
pendingUpdateRef.current = null; |
|
|
}, []); |
|
|
|
|
|
return { |
|
|
debouncedUpdate, |
|
|
flushUpdate, |
|
|
cancelUpdate |
|
|
}; |
|
|
}; |
|
|
|