Skip to content

Instantly share code, notes, and snippets.

@ds300
Created September 15, 2023 09:52
Show Gist options
  • Save ds300/35962c85c3b1a0355591c77fae8d7031 to your computer and use it in GitHub Desktop.
Save ds300/35962c85c3b1a0355591c77fae8d7031 to your computer and use it in GitHub Desktop.
usePoller.ts
import { useCallback, useEffect, useMemo } from 'react'
export class Poller<T> {
private interval: ReturnType<typeof setInterval> | null = null
constructor(
private readonly callback: (arg: { didCancelRef: { current: boolean } }) => T,
private readonly intervalMs: number
) {}
readonly didCancelRef = { current: false }
start() {
if (this.interval) clearInterval(this.interval)
this.didCancelRef.current = false
this.interval = setInterval(() => {
this.callback({ didCancelRef: this.didCancelRef })
}, this.intervalMs)
}
stop() {
this.didCancelRef.current = true
if (this.interval) clearInterval(this.interval)
}
force() {
this.start()
return this.callback({ didCancelRef: this.didCancelRef })
}
}
export function usePoller<T>(
callback: (arg: { didCancelRef: { current: boolean } }) => T,
duration: number,
disabled = false
): () => T {
const poller = useMemo(() => new Poller(callback, duration), [callback, duration])
useEffect(() => {
if (disabled) return
poller.start()
return () => {
poller.stop()
}
}, [poller, disabled])
return useCallback(() => poller.force(), [poller])
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment