Skip to content

Instantly share code, notes, and snippets.

@Orangetronic
Last active May 30, 2019 15:49
Show Gist options
  • Save Orangetronic/cc7230a650d510d623c5242c50483170 to your computer and use it in GitHub Desktop.
Save Orangetronic/cc7230a650d510d623c5242c50483170 to your computer and use it in GitHub Desktop.
use-pausable-timeout

This is a React hook that creates a timeout, and provides functions for pausing, resuming, and resetting that timeout.

import { useState, useEffect, useRef, useCallback } from "react"
const getInitialState = (delay, running) => ({
running,
startedAt: +new Date(),
timeRemaining: delay
})
export const usePausableTimeout = (callback, delay, running = true) => {
const savedCallback = useRef()
useEffect(() => {
savedCallback.current = () => {
callback()
}
}, [callback])
const [timerState, setTimerState] = useState(getInitialState(delay, running))
const pause = useCallback(() => {
const now = +new Date()
setTimerState({
running: false,
startedAt: null,
timeRemaining: timerState.timeRemaining - (now - timerState.startedAt)
})
}, [timerState])
const run = useCallback(() => {
const now = +new Date()
setTimerState({
running: true,
startedAt: now,
timeRemaining: timerState.timeRemaining
})
}, [timerState])
const reset = useCallback(() => {
setTimerState(getInitialState(delay, running))
}, [delay, running])
useEffect(() => {
if (timerState.running == true) {
// set the timeout
const timeout = setTimeout(
savedCallback.current,
timerState.timeRemaining
)
return () => {
// clear the timeout if this effect is cleaned up
clearTimeout(timeout)
}
}
}, [timerState])
return [pause, run, reset]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment