useDimensions icon indicating copy to clipboard operation
useDimensions copied to clipboard

Ability to listen for scroller other than document

Open curran opened this issue 6 years ago • 1 comments

I tried this library, and hit a use case where the scroll listener needed to be added to a scrollable element inside some other elements. My solution looks something like this:

import { useEffect, useLayoutEffect, useCallback } from 'react';

// Inspired by https://github.com/Swizec/useDimensions
export const useDimensions = ({ wrapperRef, scrollerRef, setDomRect }) => {
  
  // Measures the current dimensions.
  const measure = useCallback(() => {
    setDomRect(wrapperRef.current.getBoundingClientRect());
  }, [wrapperRef, setDomRect]);

  // Handles the case that the first measure causes a vertical
  // scrollbar to be introduced, which throws off the transform.
  // requestAnimationFrame effectively waits for the scrollbar to appear.
  const measureTwice = useCallback(() => {
    measure();
    requestAnimationFrame(measure);
  }, [measure]);

  // Measure the initial dimensions.
  useLayoutEffect(measureTwice, [measure]);

  // Measure the dimensions on resize.
  useEffect(() => {
    window.addEventListener('resize', measureTwice);
    return () => {
      window.removeEventListener('resize', measureTwice);
    };  
  }, [measureTwice, scrollerRef]);

  // Measure the dimensions on scroll.
  useEffect(() => {
    if (scrollerRef) {
      const scroller = scrollerRef.current;
      scroller.addEventListener('scroll', measure);
      return () => {
        scroller.removeEventListener('scroll', measure);
      };  
    }   
  }, [measure, scrollerRef]);
};

curran avatar Jul 19 '19 05:07 curran

I saw that the current code uses callback-style refs, apparently at the behest of Dan Abramov. I thought they were being phased out, so I don't know why that is.

In any case, what if you want to measure document scroll anyway? How to yet get a ref to that? Wouldn't it be better to pass the actual element somehow?

Also, how does the getBoundingClientRect introduce a scrollbar? I can't find anything on that…

wmertens avatar Aug 27 '19 08:08 wmertens