Closed
Description
Describe the bug
We keep seeing thousands of these logs in our sentry bug tracker. It occurs in the window.onerror event listener:
ResizeObserver loop completed with undelivered notifications
Frameworks/Libraries used
React 16.9.0
I'm using it in a hook useResizeObserver.ts
:
/**
* Inspired by ZeeCoder/use-resize-observer (MIT licensed).
* @see https://github.com/ZeeCoder/use-resize-observer
* @see https://github.com/juggle/resize-observer
*/
import { useEffect, useState, useRef, useMemo, RefObject } from 'react'
import { ResizeObserver } from '@juggle/resize-observer'
interface IUseResizeObserverProps<T> {
ref?: ((instance: T | null) => void) | RefObject<HTMLDivElement> | null | undefined,
onResize?: (size: { width: number, height: number }) => void
}
export interface ISize {
width?: number,
height?: number
}
const useResizeObserver = <T>({ ref, onResize }: IUseResizeObserverProps<T> = {}) => {
// `defaultRef` Has to be non-conditionally declared here whether or not it'll
// be used as that's how hooks work.
// @see https://reactjs.org/docs/hooks-rules.html#explanation
const defaultRef = useRef(null)
ref = ref || defaultRef
const [size, setSize] = useState<ISize>({
width: undefined,
height: undefined
})
// Using a ref to track the previous width / height to avoid unnecessary renders
const previous = useRef<ISize>({
width: undefined,
height: undefined
})
useEffect(() => {
if (
typeof ref !== 'object' ||
ref === null ||
!(ref.current instanceof Element)
) {
return
}
const element = ref.current
const resizeObserver = new ResizeObserver(entries => {
if (!Array.isArray(entries)) {
return
}
// Since we only observe the one element, we don't need to loop over the array
if (!entries.length) {
return
}
const entry = entries[0]
// `Math.round` is in line with how CSS resolves sub-pixel values
const newWidth = Math.round(entry.contentRect.width)
const newHeight = Math.round(entry.contentRect.height)
if (
previous.current.width !== newWidth ||
previous.current.height !== newHeight
) {
const newSize = { width: newWidth, height: newHeight }
if (onResize) {
onResize(newSize)
} else {
previous.current.width = newWidth
previous.current.height = newHeight
setSize(newSize)
}
}
})
resizeObserver.observe(element)
return () => {
resizeObserver.unobserve(element)
resizeObserver.disconnect()
}
}, [ref, onResize])
return useMemo(() => ({ ref, ...size }), [ref, size])
}
export default useResizeObserver
Smartphone (please complete the following information):
E.g. one case
- Device: iPhone
- OS: iOS 13.4
- Browser: Chrome Mobile iOS
- Version: 80.0.3987
(But we also see this on Android, Windows, Linux, iOS safari)
Metadata
Metadata
Assignees
Labels
No labels