useTimeout
A custom React Hook that allows you to set a timeout and then clear or reset it.
Props
callback (function)
: The function to be called when the timeout expires.delay (number)
: The delay in milliseconds for when the callback should be executed.
Return
reset (function)
: Resets the timeout and restarts the countdown.clear (function)
: Clears the timeout and stops the countdown.
The Hook
useTimeout.ts
import { useCallback, useRef } from 'react'
import { useIsomorphicEffect } from '../useIsomorphicEffect'
export const useTimeout = (callback: () => void, delay: number) => {
const callbackRef = useRef(callback)
const timeoutRef = useRef<number | null>()
useIsomorphicEffect(() => {
callbackRef.current = callback
}, [callback])
const set = useCallback(() => {
if (!delay && delay !== 0) {
return
}
timeoutRef.current = setTimeout(() => callbackRef.current(), delay)
}, [delay])
const clear = useCallback(() => {
timeoutRef.current && clearTimeout(timeoutRef.current)
}, [])
useIsomorphicEffect(() => {
set()
return clear()
}, [delay, set, clear])
const reset = useCallback(() => {
clear()
set()
}, [clear, set])
return { reset, clear }
}
Usage
UseTimeoutDemo.tsx
import React, { useState } from 'react'
import { useTimeout } from './useTimeout'
export const UseTimeoutDemo = () => {
const [count, setCount] = useState(10)
const { reset, clear } = useTimeout(() => setCount(0), 5000)
return (
<div>
<div>{count}</div>
<button onClick={() => setCount((c) => c + 1)}>Increment</button>
<button onClick={clear}>Clear Timeout</button>
<button onClick={reset}>Reset Timeout</button>
<p>{count ? 'Timeout visible for 5000ms' : 'Timeout expired!'}</p>
</div>
)
}