Skip to content

Commit

Permalink
[Masonry] Fix ResizeObserver loop limit exceeded error (#37208)
Browse files Browse the repository at this point in the history
  • Loading branch information
hbjORbj authored Jun 20, 2023
1 parent f26df6a commit 6c93a3b
Showing 1 changed file with 24 additions and 9 deletions.
33 changes: 24 additions & 9 deletions packages/mui-lab/src/Masonry/Masonry.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ import {
handleBreakpoints,
unstable_resolveBreakpointValues as resolveBreakpointValues,
} from '@mui/system';
import { deepmerge, unstable_useForkRef as useForkRef } from '@mui/utils';
import {
deepmerge,
unstable_useForkRef as useForkRef,
unstable_useEnhancedEffect as useEnhancedEffect,
} from '@mui/utils';
import clsx from 'clsx';
import PropTypes from 'prop-types';
import * as React from 'react';
Expand Down Expand Up @@ -211,6 +215,7 @@ const Masonry = React.forwardRef(function Masonry(inProps, ref) {
if (!masonryRef.current || !masonryChildren || masonryChildren.length === 0) {
return;
}

const masonry = masonryRef.current;
const masonryFirstChild = masonryRef.current.firstChild;
const parentWidth = masonry.clientWidth;
Expand Down Expand Up @@ -272,23 +277,33 @@ const Masonry = React.forwardRef(function Masonry(inProps, ref) {
}
};

const observer = React.useRef(
typeof ResizeObserver === 'undefined' ? undefined : new ResizeObserver(handleResize),
);

React.useEffect(() => {
const resizeObserver = observer.current;
useEnhancedEffect(() => {
// IE and old browsers are not supported
if (resizeObserver === undefined) {
if (typeof ResizeObserver === 'undefined') {
return undefined;
}

let animationFrame;

const resizeObserver = new ResizeObserver(() => {
// see https://github.com/mui/material-ui/issues/36909
animationFrame = window.requestAnimationFrame(handleResize);
});

if (masonryRef.current) {
masonryRef.current.childNodes.forEach((childNode) => {
resizeObserver.observe(childNode);
});
}
return () => (resizeObserver ? resizeObserver.disconnect() : {});

return () => {
if (animationFrame) {
window.cancelAnimationFrame(animationFrame);
}
if (resizeObserver) {
resizeObserver.disconnect();
}
};
}, [columns, spacing, children]);

const handleRef = useForkRef(ref, masonryRef);
Expand Down

0 comments on commit 6c93a3b

Please sign in to comment.