Real World Example

Real World: Tooltips and dropdown menus

A tooltip must be placed above or below a button depending on free space. Measuring in useLayoutEffect positions it before the user sees it, so it never jumps.

function Tooltip({ targetRef, text }) {
  const tipRef = useRef(null);
  const [top, setTop] = useState(0);

  useLayoutEffect(() => {
    const target = targetRef.current.getBoundingClientRect();
    const tip = tipRef.current.getBoundingClientRect();
    const above = target.top - tip.height - 8;
    setTop(above > 0 ? above : target.bottom + 8);   // flip below if no space
  }, [targetRef]);

  return <div ref={tipRef} className="tooltip" style={{ top }}>{text}</div>;
}