Created
October 6, 2021 07:53
-
-
Save donaldpipowitch/6f15d90ec964936d3011b9b594be80cc to your computer and use it in GitHub Desktop.
use-timeout.ts
This file contains hidden or 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
// it's like setTimeout as a hook, but with a small twist: | |
// you can make multiple subsequent calls and can increase or decrease | |
// the delay (e.g. useful to create polling like functionality) | |
type Options = { | |
delay: number; | |
multiplier?: number; | |
}; | |
type State = { | |
running: boolean; | |
count: number; | |
delay: number; | |
callback?: Function; | |
}; | |
function useTimeout(options: Options) { | |
const initialDelay = options.delay; | |
const multiplier = options.multiplier ?? 1; | |
const initialState = useMemo<State>( | |
() => ({ | |
running: false, | |
count: 0, | |
delay: initialDelay, | |
}), | |
[initialDelay] | |
); | |
const [state, setState] = useState<State>(initialState); | |
useEffect(() => { | |
if (!state.count) return; | |
const timeoutId = setTimeout(() => { | |
setState((state) => ({ | |
...state, | |
running: false, | |
delay: state.delay * multiplier, | |
})); | |
state.callback?.(); | |
}, state.delay); | |
return () => clearTimeout(timeoutId); | |
// eslint-disable-next-line react-hooks/exhaustive-deps | |
}, [state.count]); | |
const next = useCallback( | |
(callback: Function) => | |
setState((state) => ({ | |
...state, | |
running: true, | |
count: state.count + 1, | |
callback, | |
})), | |
[] | |
); | |
const reset = useCallback(() => setState(initialState), [initialState]); | |
const { running, count, delay } = state; | |
const value = useMemo( | |
() => ({ count, delay, next, reset, running }), | |
[count, delay, next, reset, running] | |
); | |
return value; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment