React Material-UI 菜单锚被 react-window 列表破坏

IT技术 reactjs material-ui
2021-04-20 07:20:53

我在一个项目中使用 Material-UI 和 react-window。我的问题是,当该元素位于 react-window 虚拟化列表中时,material-ui 菜单组件不会锚定到提供的元素。菜单将出现在屏幕的左上角,而不是锚定在打开它的按钮上。在非虚拟化列表中使用它时,它按预期工作。菜单正确锚定到打开它的按钮。

这是一个示例沙箱沙箱非常特定于我如何使用相关组件。

有关如何解决此问题的任何指导?

2个回答

这是您的沙箱的修改版本,可以解决此问题:

编辑 BigList 菜单

这是您的初始代码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类似于代码的固定版本现在是结构化的。

这是一个非常有帮助的答案。谢谢你。
2021-05-25 07:20:53

瑞安感谢您的回答!它帮助了我!

还有另一种解决方案:将父组件定义为类组件(而不是功能组件)。

我的问题是我正在像这样调用 'Rows' 函数:

 <FixedSizeList
     height={height}
     itemCount={nodes.length}
     itemSize={50}
     width={width}
     overscanCount={10}
    >
        {({ index, style }) => this.renderListItem(nodes[index], style)}
    </FixedSizeList>

修复类似于 Ryan 建议的:

render() {
 ...
 return <FixedSizeList
     height={height}
     itemCount={nodes.length}
     itemSize={50}
     width={width}
     overscanCount={10}
     itemData={nodes}
    >
        {this.renderListItem}
    </FixedSizeList>
  }

  renderListItem = ({data,index, style}) => {
    ...
  }

我使用itemDataprop 来访问函数nodes内部的数组renderListItem