[v11.1.x] Scrollbar: fix scrollTo being called on stale reference (#90491)

Scrollbar: fix scrollTo being called on stale reference (#90346)

* fix: fix scrollTo being called on stale reference

(cherry picked from commit bb52c340cc)

Co-authored-by: Galen Kistler <109082771+gtk-grafana@users.noreply.github.com>
This commit is contained in:
grafana-delivery-bot[bot]
2024-07-16 19:52:29 +03:00
committed by GitHub
co-authored by Galen Kistler
parent 7e9f8a8779
commit 104daa45db
@@ -60,11 +60,7 @@ export const CustomScrollbar = ({
}
}, [ref, scrollRefCallback]);
useEffect(() => {
if (ref.current && scrollTop != null) {
ref.current.scrollTop(scrollTop);
}
}, [scrollTop]);
useScrollTop(ref.current, scrollTop);
/**
* Special logic for doing a update a few milliseconds after mount to check for
@@ -216,3 +212,21 @@ const getStyles = (theme: GrafanaTheme2) => {
}),
};
};
/**
* Calling scrollTop on a scrollbar ref in a useEffect can race with internal state in react-custom-scrollbars-2, causing scrollTop to get called on a stale reference, which prevents the element from scrolling as desired.
* Adding the reference to the useEffect dependency array not notify react that the reference has changed (and is an eslint violation), so we create a custom hook so updates to the reference trigger another render, fixing the race condition bug.
*
* @param scrollBar
* @param scrollTop
*/
function useScrollTop(
scrollBar: (Scrollbars & { view: HTMLDivElement; update: () => void }) | null,
scrollTop?: number
) {
useEffect(() => {
if (scrollBar && scrollTop != null) {
scrollBar.scrollTop(scrollTop);
}
}, [scrollTop, scrollBar]);
}