Skip to content

Instantly share code, notes, and snippets.

@slinkardbrandon
Created April 28, 2021 01:17
Show Gist options
  • Save slinkardbrandon/5b87910e54c40af76b3ed94b6c9a5cb6 to your computer and use it in GitHub Desktop.
Save slinkardbrandon/5b87910e54c40af76b3ed94b6c9a5cb6 to your computer and use it in GitHub Desktop.
A simple hook leveraging lodash debounce to create a debounced callback that persists properly across renders
import { debounce } from 'lodash';
import { useCallback, useRef } from 'react';
type Callback = (...args: any[]) => void;
/**
* Create the memoized / debounced function one time.
*
* This stores the current instance of the function to be debounced in a ref and updates
* it every render (preventing stale data). Instead of debouncing that function directly we
* debounce a wrapper function that reads the current version from the ref and call that.
*/
export function useDebouncedCallback(callback: Callback, delay: number) {
const callbackRef = useRef<Callback>();
callbackRef.current = callback;
return useCallback(
debounce((...args) => callbackRef.current?.(...args), delay),
[]
);
}
@slinkardbrandon
Copy link
Author

Usage:

  const onChange = useDebouncedCallback((val: string) => {
    console.log('debounced with value', val);
  }, 300);

  return (
    <input type="text" onChange={onChange} />
  )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment