mirror of
https://github.com/zoriya/react-native-web.git
synced 2026-05-31 09:44:21 +00:00
[fix] Avoid needing to memoize onLayout callbacks
If 'onLayout' is an inline function, it could cause the DOM node to enter a cycle of being observed/unobserved with the result that 'onLayout' was constantly called. Fix #1704
This commit is contained in:
+16
-7
@@ -61,23 +61,32 @@ function getResizeObserver(): ?ResizeObserver {
|
||||
|
||||
export default function useElementLayout(
|
||||
ref: ElementRef<any>,
|
||||
onLayout?: (e: LayoutEvent) => void
|
||||
onLayout?: ?(e: LayoutEvent) => void
|
||||
) {
|
||||
const observer = getResizeObserver();
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const node = ref.current;
|
||||
if (node != null && observer != null && typeof onLayout === 'function') {
|
||||
observer.observe(node);
|
||||
// $FlowFixMe
|
||||
if (node != null) {
|
||||
node[DOM_LAYOUT_HANDLER_NAME] = onLayout;
|
||||
}
|
||||
}, [ref, onLayout]);
|
||||
|
||||
// Observing is done in a separate effect to avoid this effect running
|
||||
// when 'onLayout' changes.
|
||||
useLayoutEffect(() => {
|
||||
const node = ref.current;
|
||||
if (node != null && observer != null) {
|
||||
if (typeof node[DOM_LAYOUT_HANDLER_NAME] === 'function') {
|
||||
observer.observe(node);
|
||||
} else {
|
||||
observer.unobserve(node);
|
||||
}
|
||||
}
|
||||
return () => {
|
||||
if (node != null && observer != null) {
|
||||
observer.unobserve(node);
|
||||
// $FlowFixMe
|
||||
delete node[DOM_LAYOUT_HANDLER_NAME];
|
||||
}
|
||||
};
|
||||
}, [ref, onLayout, observer]);
|
||||
}, [ref, observer]);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user