React Material-UI菜单锚被react-window列表破坏 [英] React Material-UI menu anchor broken by react-window list

查看:78
本文介绍了React Material-UI菜单锚被react-window列表破坏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

这是示例沙箱.沙盒非常特定于我如何使用有问题的组件.

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

解决方案

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

这是您在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. /p>

您会在react-window文档中注意到( https: //react-window.now.sh/#/examples/list/fixed-size )Row组件是在Example组件外部定义的,类似于现在固定代码版本的结构

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.

这篇关于React Material-UI菜单锚被react-window列表破坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆