这是一个修改后的沙盒版本,可以解决这个问题:
这是您在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>
);
};
我将其更改为以下内容:
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>
);
};
重要的区别在于Row 现在是一个一致的组件类型,而不是在每次渲染BigList 时重新定义。使用您的初始代码,BigList 的每次渲染都会导致所有 FancyListItem 元素被重新安装,而不是仅仅重新渲染,因为它周围代表“行”类型的函数是一个新函数,每次渲染 BigList。这样做的一个影响是,您传递给Menu 的锚元素在Menu 尝试确定其位置并且anchorEl.getBoundingClientRect() 提供的x,y 位置为0,0 时不再安装。
您会在 react-window 文档 (https://react-window.now.sh/#/examples/list/fixed-size) 中注意到 Row 组件是在 Example 组件之外定义的,类似于您的代码的固定版本现在的结构。