-
Notifications
You must be signed in to change notification settings - Fork 2
Open
Description
Here is a possible implementation
import { useState, useRef, useCallback, useEffect } from "react";
interface UsePollingProps {
callback: () => void | Promise<void>,
interval: number,
stopped: boolean
}
interface UsePollingResult {
isPolling: boolean;
startPolling(): void;
stopPolling(): void;
}
const usePolling = (props: UsePollingProps): UsePollingResult => {
const { callback, interval, stopped } = props;
const [isPolling, setIsPolling] = useState(false);
const persistedIsPolling = useRef<boolean>();
const timeout = useRef<NodeJS.Timeout>();
persistedIsPolling.current = isPolling;
const stopPolling = useCallback(() => {
clearTimeout(timeout.current);
setIsPolling(false);
}, []);
const runPolling = useCallback(() => {
timeout.current = setTimeout(async () => {
try {
await callback();
} finally {
persistedIsPolling.current ? runPolling() : stopPolling();
}
}, interval);
}, [callback, interval, stopPolling]);
const startPolling = useCallback(() => {
setIsPolling(true);
runPolling();
}, [runPolling]);
useEffect(() => {
if (!stopped) {
startPolling();
}
return () => {
stopPolling();
};
}, [interval, stopped, startPolling, stopPolling]);
return {
isPolling,
startPolling,
stopPolling,
};
};
export { usePolling };
Metadata
Metadata
Assignees
Labels
No labels