Skip to content

Instantly share code, notes, and snippets.

@mrousavy
Created June 30, 2020 12:29
Show Gist options
  • Save mrousavy/02fc67ad1a32b167d299cf7f1dd6fea4 to your computer and use it in GitHub Desktop.
Save mrousavy/02fc67ad1a32b167d299cf7f1dd6fea4 to your computer and use it in GitHub Desktop.
A React hook similar to useEffect, but with a custom timeout to debounce an extra function, for example fetch data from a server when the text changes.
import { useEffect, useRef } from 'react';
/**
* Like useEffect but with a custom timeout to debounce an extra function, for example fetch data from a server when the text changes.
* @param shouldExecuteDebounce A function (created with `useCallback`!) which checks whether the `debounceExecute` function should be executed (after it's debounce delay).
* @param debouncedExecute A function (created with `useCallback`!) to run after `{debounceMs}` milliseconds. This function only gets executed, when this hook doesn't re-run within `{debounceMs}` milliseconds after the execution of the `alwaysExecute` function. Note: Because of it's async nature, this function cannot return a cleanup function.
* @param debounceMs The milliseconds to wait until the debounce function gets executed
* @example
* useDebouncedEffect(
* useCallback(() => {
* setLoading(true)
* return true;
* }, [setLoading]),
* useCallback(() => fetchNewDataFromServer(searchText), [fetchNewDataFromServer, searchText]),
* 700
* );
*/
export default function useDebouncedEffect(shouldExecuteDebounce: () => boolean, debouncedExecute: () => unknown, debounceMs: number): void {
const lastUpdate = useRef<Date | undefined>(undefined);
useEffect(() => {
const now = new Date();
lastUpdate.current = now;
const shouldExecute = shouldExecuteDebounce();
if (shouldExecute) {
setTimeout(() => {
if (lastUpdate.current !== now) return;
debouncedExecute();
}, debounceMs);
}
}, [debounceMs, debouncedExecute, shouldExecuteDebounce]);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment