import { useEffect , useRef , useState } from 'react' ; import useUnmount from './useUnmount' ; const useThrottleFn = < T , U extends any [ ] > ( fn , ms = 200 , args ) => { const [ state , setState ] = useState < T | null > ( null ) ; const timeout = useRef < ReturnType < typeof setTimeout > > ( ) ; const nextArgs = useRef < U > ( ) ; useEffect ( ( ) => { if ( ! timeout . current ) { setState ( fn ( ... args ) ) ; const timeoutCallback = ( ) => { if ( nextArgs . current ) { setState ( fn ( ... nextArgs . current ) ) ; nextArgs . current = undefined ; timeout . current = setTimeout ( timeoutCallback , ms ) ; } else { timeout . current = undefined ; } } ; timeout . current = setTimeout ( timeoutCallback , ms ) ; } else { nextArgs . current = args ; } } , args ) ; useUnmount ( ( ) => { timeout . current && clearTimeout ( timeout . current ) ; } ) ; return state ; } ; export default useThrottleFn ;