React Material-UI menu anchor broken by react-window list
I am using Material-UI and react-window in a project. My issue is, the material-ui menu component does not anchor to the element provided when that element is within a react-window virtualized list. The menu will appear in the upper left corner of the screen instead of anchored to the button that opens it. When using it all in a non-virtualized list, it works as expected. The menu properly anchors to the button that opens it.
Here's an example sandbox. The sandbox is pretty specific to how I'm using the components in question.
Any guidance on how I can resolve this?
Here's a modified version of your sandbox that fixes this:
Here was your initial code in BigList
:
const BigList = props => {
const { height, ...others } = props;
const importantData = Array(101 - 1)
.fill()
.map((_, idx) => 0 + idx);
const rows = ({ index, style }) => (
<FancyListItem
index={index}
styles={style}
text="window'd (virtual): "
{...others}
/>
);
return (
<FixedSizeList
height={height}
itemCount={importantData.length}
itemSize={46}
outerElementType={List}
>
{rows}
</FixedSizeList>
);
};
I changed this to the following:
const Row = ({ data, index, style }) => {
return (
<FancyListItem
index={index}
styles={style}
text="window'd (virtual): "
{...data}
/>
);
};
const BigList = props => {
const { height, ...others } = props;
const importantData = Array(101 - 1)
.fill()
.map((_, idx) => 0 + idx);
return (
<FixedSizeList
height={height}
itemCount={importantData.length}
itemSize={46}
outerElementType={List}
itemData={others}
>
{Row}
</FixedSizeList>
);
};
The important difference is that Row
is now a consistent component type rather than being redefined with every render of BigList
. With your initial code, every render of BigList
caused all of the FancyListItem
elements to be remounted rather than just rerendered because the function around it representing the "row" type was a new function with each rendering of BigList
. One effect of this is that the anchor element you were passing to Menu
was no longer mounted by the time Menu
tried to determine its position and anchorEl.getBoundingClientRect() was providing an x,y position of 0,0.
You'll notice in the react-window documentation (https://react-window.now.sh/#/examples/list/fixed-size) the Row
component is defined outside of the Example
component similar to how the fixed version of your code is now structured.