#2675·react-use

`useScrolling` doesn't clean up its timer

Author: stevebaxterCreated Oct 19, 2025Updated Feb 19, 2026

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.