How to use DOMRect with useEffect in React?

Viewed 736

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?

1 Answers

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]);
Related