-
-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Open
Description
What is the current behavior?
useScrolling
can leave a timer running on unmount because it doesn't clean up correctly.
I think we need to update the code to something like:
const useScrolling = (ref: RefObject<HTMLElement>): boolean => {
const [scrolling, setScrolling] = useState<boolean>(false);
useEffect(() => {
if (ref.current) {
let scrollingTimeout: ReturnType<typeof setTimeout>;
const handleScrollEnd = () => {
setScrolling(false);
};
const handleScroll = () => {
setScrolling(true);
clearTimeout(scrollingTimeout);
scrollingTimeout = setTimeout(() => handleScrollEnd(), 150);
};
on(ref.current, "scroll", handleScroll, false);
return () => {
// This is the change from the original implementation
clearTimeout(scrollingTimeout);
if (ref.current) {
off(ref.current, "scroll", handleScroll, false);
}
};
}
return () => {};
}, [ref]);
return scrolling;
}
We need to call clearTimeout()
in the cleanup function to correctly remove the timeout.
Steps to reproduce it and if possible a minimal demo of the problem:
This turned up intermittently in our Jest tests.
What is the expected behavior?
The timeout should be cleaned up.
A little about versions:
- OS:
macOS 26 - Browser (vendor and version):
Node 22.12 (in tests) - React:
17.0.2 react-use
:
17.3.1- Did this worked in the previous package version?
No, it looks like the same issue is present in master.
Metadata
Metadata
Assignees
Labels
No labels