react-use-measure icon indicating copy to clipboard operation
react-use-measure copied to clipboard

Doesn't measure position updates when size doesn't change

Open nicholaschiang opened this issue 4 years ago • 1 comments
trafficstars

I'm not sure if the issue title above is 100% correct, but I think it's the best way to describe my issue.

See this code sandbox and notice that the rightX variable doesn't update properly when the div's min-width is met (and the bottom scroller appears):

use-measure-wrong

It only updates to the correct position after the div is scrolled. On the other hand, the wrapper div position is correct until the div is scrolled.

useMeasure should report the correct position of the child div (the one with the scrollbar) when the parent moves.

nicholaschiang avatar Feb 22 '21 00:02 nicholaschiang

Found a temporary solution (the "TRUE X" is always correct):

export default function App() {
  const [open, setOpen] = useState(false);
  const leftProps = useSpring({ config, width: open ? 400 : 0 });
  const [leftRef, { x: leftX }] = useMeasure({ polyfill });
  const rightProps = useSpring({ config, marginLeft: open ? 400 : 0 });
  const [realRightRef, { x: realRightX }] = useMeasure({ polyfill });
  const [rightRef, { x: rightX }] = useMeasure({ polyfill, scroll: true });

  // Current workaround is to listen for scrolls on the parent div. Once
  // the user scrolls, we know that the `realRightX` is no longer correct
  // but that the `rightX` is correct.
  const [rightXCorrect, setRightXCorrect] = useState(false);
  useEffect(() => {
    setRightXCorrect(false);
  }, [open]);

  return (
    <div className="app">
      <button onClick={() => setOpen((prev) => !prev)}>TOGGLE</button>
      <span className="toggle-label">{open ? "OPEN" : "CLOSED"}</span>
      <div className="wrapper">
        <animated.div style={leftProps} className="left">
          <div ref={leftRef} className="left-content">
            LEFT X: {leftX}
          </div>
        </animated.div>
        <animated.div style={rightProps} className="right">
          <div
            ref={realRightRef}
            onScroll={() => setRightXCorrect(true)}
            className="right-wrapper"
          >
            <div ref={rightRef} className="right-content">
              REAL X: {realRightX}
              <br />
              RIGHT X: {rightX}
              <br />
              TRUE X: {rightXCorrect ? rightX : realRightX}
            </div>
          </div>
        </animated.div>
      </div>
    </div>
  );
}

nicholaschiang avatar Feb 22 '21 00:02 nicholaschiang