UNPKG

@linzjs/step-ag-grid

Version:

[![semantic-release: angular](https://img.shields.io/badge/semantic--release-angular-e10079?logo=semantic-release)](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
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(); } }; }, []); }