2

I am trying to get the x and y of an element in React. I can do it just fine using DOMRect, but not in the first render. That's how my code is right now:

const Circle: React.FC<Props> = ({ children }: Props) => {
  const context = useContext(ShuffleMatchContext);
  const circle: React.RefObject<HTMLDivElement> = useRef(null);
  const { width, height } = useWindowDimensions();

  useEffect(() => {
    const rect = circle.current?.getBoundingClientRect();
    context.setQuestionPosition({
      x: rect!.x,
      y: rect!.y,
    });
  }, [width, height]);

  return (
    <>
      <Component
        ref={circle}
      >
        <>{children}</>
      </Component>
    </>
  );
};

export default Circle;

The problem is that on the first render, domRect returns 0 to everything inside it. I assume this behavior happens because, in the first render, you don't have all parent components ready yet. I used a hook called "useWindowDimensions," and in fact, when you resize the screen, domRect returns the expected values. Can anyone help?

Artur
  • 21
  • 3

1 Answers1

1

You should use useLayoutEffect(). It allows you to get the correct DOM-related values (i.e. the dimensions of a specific element) since it fires synchronously after all DOM mutations.

useLayoutEffect(() => {
  const rect = circle.current?.getBoundingClientRect();
  context.setQuestionPosition({
    x: rect!.x,
    y: rect!.y,
  });
}, [width, height]);
Rax Weber
  • 3,730
  • 19
  • 30
  • 1
    I thought it could be that too, initially. However, useLayoutEffect is working just like useEffect and DOMRect is returning 0 for all values in the first render :/ – Artur Mar 05 '21 at 14:41
  • Can you post also the `Component` file? – Rax Weber Mar 05 '21 at 14:45
  • I put the whole file in a sandbox: https://codesandbox.io/s/fancy-silence-l96wm?file=/src/App.js – Artur Mar 05 '21 at 14:59
  • I believe it has something to do with the component where you pass the `ref`. You can check https://stackoverflow.com/questions/60881446/receive-dimensions-of-element-via-getboundingclientrect-in-react. – Rax Weber Mar 05 '21 at 15:21