@react-hookz/web
Version:
React hooks done right, for browser and SSR.
41 lines (40 loc) • 1.31 kB
JavaScript
import { useCallback, useEffect, useRef } from 'react';
import { useSyncedRef } from '../useSyncedRef/index.js';
const cancelTimeout = (id) => {
if (id) {
clearTimeout(id);
}
};
/**
* Like `setTimeout` but in the form of a react hook.
*
* @param callback Callback to be called after the timeout. Changing this
* will not reset the timeout.
* @param ms Timeout delay in milliseconds. `undefined` disables the timeout.
* Keep in mind, that changing this parameter will re-set timeout, meaning
* that it will be set as new after the change.
*/
export function useTimeoutEffect(callback, ms) {
const cbRef = useSyncedRef(callback);
const msRef = useSyncedRef(ms);
const timeoutIdRef = useRef(null);
const cancel = useCallback(() => {
cancelTimeout(timeoutIdRef.current);
}, []);
const reset = useCallback(() => {
if (msRef.current === undefined) {
return;
}
cancel();
timeoutIdRef.current = setTimeout(() => {
cbRef.current();
}, msRef.current);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => {
reset();
return cancel;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [ms]);
return [cancel, reset];
}