UNPKG

@1771technologies/lytenyte-pro

Version:

Blazingly fast headless React data grid with 100s of features.

38 lines (37 loc) 1.67 kB
import { useRef } from "react"; import { useEvent } from "@1771technologies/lytenyte-core/internal"; import { equal } from "@1771technologies/js-utils"; export function useOnViewChange(source, requestsForView, setRequestsForView, debounceDuration) { const timerRef = useRef(null); const pendingBoundsRef = useRef(null); // Reads latest requestsForView/setRequestsForView at call time (via useEvent), so the // timer always flushes against the current state even if renders occurred while pending. const flush = useEvent(() => { const bounds = pendingBoundsRef.current; if (!bounds) return; pendingBoundsRef.current = null; source.rowViewBounds = bounds; const requests = source.requestsForView(); if (!equal(requests, requestsForView)) setRequestsForView(requests); }); const onViewChange = useEvent((bounds) => { if (debounceDuration <= 0) { source.rowViewBounds = [bounds.rowCenterStart, bounds.rowCenterEnd]; const requests = source.requestsForView(); if (!equal(requests, requestsForView)) setRequestsForView(requests); return; } // Store the latest bounds so the timer always flushes with the final scroll position, not an intermediate one. pendingBoundsRef.current = [bounds.rowCenterStart, bounds.rowCenterEnd]; if (timerRef.current !== null) clearTimeout(timerRef.current); timerRef.current = setTimeout(() => { timerRef.current = null; flush(); }, debounceDuration); }); return onViewChange; }