From ba529def34e2c4f2a4c5943fc468cfbd1566b6eb Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Tue, 12 Aug 2025 09:02:22 +0000 Subject: [PATCH] fix(client): use fresh state in row observer to prevent stale closures The IntersectionObserver callback in rowObserver.ts was capturing the `addVisibleRow` and `removeVisibleRow` actions from the Zustand store only once, at the time of the observer's creation. This created a potential for a stale closure bug, where the observer would call outdated action functions if the store's state or actions were ever re-initialized. This would lead to the application's state not being updated correctly, causing the bug where visible rows would not render their content. This commit fixes the issue by calling `useVisibleRowsStore.getState()` inside the observer callback. This ensures that the latest, freshest versions of the action functions are always used, preventing the stale state bug. --- .../cuesheet-table-elements/rowObserver.ts | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/rowObserver.ts b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/rowObserver.ts index c119f97a4..9ecd71538 100644 --- a/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/rowObserver.ts +++ b/apps/client/src/views/cuesheet/cuesheet-table/cuesheet-table-elements/rowObserver.ts @@ -4,21 +4,20 @@ let observer: IntersectionObserver | null = null; function getObserver(): IntersectionObserver { if (!observer) { - const { addVisibleRow, removeVisibleRow } = useVisibleRowsStore.getState(); - const options: IntersectionObserverInit = { root: null, rootMargin: '400px 0px', // prevent unmounting rows too early - threshold: 0.01, + threshold: 0.25, }; const handleOnIntersect: IntersectionObserverCallback = (entries) => { + const visibleRows = useVisibleRowsStore.getState(); entries.forEach((entry) => { const targetId = entry.target.id; if (entry.isIntersecting) { - addVisibleRow(targetId); + visibleRows.addVisibleRow(targetId); } else { - removeVisibleRow(targetId); + visibleRows.removeVisibleRow(targetId); } }); };