Last active
September 17, 2024 14:50
-
-
Save odahcam/01f1057d20d9de3e278b8fd4fdb632bd to your computer and use it in GitHub Desktop.
React hook for polling any given callback.
This file contains 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
import { useEffect, useRef } from 'react'; | |
const defaultInterval = 30e3; | |
export function usePolling(callback: () => Promise<void>, dependencies: any[] = [], interval: number = defaultInterval) { | |
const savedCallback = useRef<() => Promise<void>>(); | |
const intervalId = useRef<NodeJS.Timeout | null>(null); | |
// Store the latest callback in a ref to avoid recreating the effect on every render | |
useEffect(() => { | |
savedCallback.current = callback; | |
}, [callback]); | |
// The polling effect | |
useEffect(() => { | |
let isCancelled = false; | |
const tick = async () => { | |
if (!isCancelled && savedCallback.current) { | |
await savedCallback.current(); | |
if (!isCancelled) { | |
intervalId.current = setTimeout(tick, interval); | |
} | |
} | |
}; | |
// Start polling immediately and also when dependencies change | |
tick(); | |
// Cleanup function to stop polling | |
return () => { | |
isCancelled = true; | |
if (intervalId.current) { | |
clearTimeout(intervalId.current); | |
} | |
}; | |
}, [...dependencies, interval]); // Include dependencies to trigger re-run, and the interval as the last one | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment