Created
June 30, 2020 12:29
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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