JAVASCRIPT
Implement Data Polling with `usePolling` for Real-time Updates
Create a `usePolling` custom hook in React to periodically fetch data from an API, enabling real-time dashboards or background updates with customizable intervals.
import { useEffect, useRef, useState } from 'react';
function usePolling(callback, delay, dependencies = []) {
const savedCallback = useRef();
const [isPolling, setIsPolling] = useState(false);
// Remember the latest callback.
useEffect(() => {
savedCallback.current = callback;
}, [callback]);
// Set up the interval.
useEffect(() => {
function tick() {
savedCallback.current();
}
if (delay !== null) {
setIsPolling(true);
tick(); // Run immediately on mount/dependency change
const id = setInterval(tick, delay);
return () => {
clearInterval(id);
setIsPolling(false);
};
} else {
setIsPolling(false);
}
}, [delay, ...dependencies]); // Re-run effect if delay changes or any dependency changes
return isPolling;
}
// How to use it:
// function LiveDataDisplay() {
// const [data, setData] = useState([]);
// const [loading, setLoading] = useState(false);
//
// const fetchData = async () => {
// setLoading(true);
// try {
// const response = await fetch('https://api.example.com/live-data');
// const json = await response.json();
// setData(json.items);
// } catch (error) {
// console.error('Failed to fetch live data:', error);
// } finally {
// setLoading(false);
// }
// };
//
// const isPolling = usePolling(fetchData, 3000); // Fetch data every 3 seconds
//
// return (
// <div>
// <h2>Live Data</h2>
// {loading && <p>Loading...</p>}
// {!loading && data.length === 0 && <p>No data available.</p>}
// <ul>
// {data.map((item, index) => (
// <li key={index}>{item.name}</li>
// ))}
// </ul>
// <p>Polling Status: {isPolling ? 'Active' : 'Inactive'}</p>
// </div>
// );
// }
How it works: The `usePolling` hook provides a way to execute a given `callback` function repeatedly at a specified `delay` interval. It utilizes `useEffect` and `setInterval` to manage the polling cycle. The `callback` is also immediately invoked when the component mounts or when its dependencies change, ensuring fresh data. `useRef` is used to keep the `callback` up-to-date without restarting the interval unnecessarily. It returns a boolean indicating if polling is currently active.