@linzjs/step-ag-grid
Version:
[](https://github.com/semantic-release/semantic-release) > Reusable [ag-grid](https://www.ag-grid.com/) component for LINZ / Toitū te whenua.
58 lines (48 loc) • 1.37 kB
text/typescript
import { useEffect, useRef } from 'react';
import { useIsomorphicLayoutEffect } from 'usehooks-ts';
type Callback = () => void;
const isNode = typeof process !== 'undefined' && process.env.NODE_ENV === 'test';
let sharedIntervalId: ReturnType<typeof setInterval> | null = null;
const callbacks = new Set<Callback>();
const startSharedInterval = () => {
if (isNode || sharedIntervalId !== null) {
return;
}
sharedIntervalId = setInterval(() => {
callbacks.forEach((cb) => {
try {
cb();
} catch (e) {
console.error(e);
}
});
}, 100);
}
const stopSharedInterval = () => {
if (sharedIntervalId === null) {
return;
}
clearInterval(sharedIntervalId);
sharedIntervalId = null;
}
/**
* Like useInterval, but all callers share a single 100ms interval.
* Each callback is isolated in a try/catch so a throwing callback won't prevent others from running.
*/
export const useSharedInterval = (callback: () => void) => {
const savedCallback = useRef(callback);
useIsomorphicLayoutEffect(() => {
savedCallback.current = callback;
}, [callback]);
useEffect(() => {
const cb = () => savedCallback.current();
callbacks.add(cb);
startSharedInterval();
return () => {
callbacks.delete(cb);
if (callbacks.size === 0) {
stopSharedInterval();
}
};
}, []);
}