Open dontsave opened 1 year ago
I workaround this by manually setting an initial rect:
const betterContainerRef = useCallback((element: HTMLDivElement | null) => {
if (element) setInitialRect(element.getBoundingClientRect());
containerRef(element); // from react-use-measure
}, []);
I use the initial rect whenever the measured rect is 0. This helped to avoid the visual glitch for me.
FYI: I use this now:
// inspired by https://github.com/streamich/react-use/blob/master/src/useMeasure.ts
import { useLayoutEffect, useMemo, useState } from 'react';
export type RectReadOnly = Pick<
DOMRectReadOnly,
'x' | 'y' | 'top' | 'left' | 'right' | 'bottom' | 'height' | 'width'
>;
const defaultState: RectReadOnly = {
x: 0,
y: 0,
width: 0,
height: 0,
top: 0,
left: 0,
bottom: 0,
right: 0,
};
export function useMeasure() {
const [element, ref] = useState<HTMLDivElement | null>(null);
const [rect, setRect] = useState(defaultState);
const observer = useMemo(
() =>
new ResizeObserver((entries) => {
if (entries[0]) {
setRect(entries[0].target.getBoundingClientRect());
}
}),
[]
);
useLayoutEffect(() => {
if (!element) return;
setRect(element.getBoundingClientRect());
observer.observe(element);
return () => {
observer.disconnect();
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [element]);
return [ref, rect] as const;
}
hi there. just wanted to flag a little bug with setting state from ResizeObserver callbacks that happens in React 18 due to setState batching. we are seeing this issue surface in
react-use-measure
currently. the solution is to wrap the internalsetState
influshSync
fromReactDOM
:https://github.com/facebook/react/issues/24331
there may be performance ramifications in doing this, so it might be a good thing to have as opt-in