【问题标题】:React Material-UI menu anchor broken by react-window listReact Material-UI 菜单锚被 react-window 列表破坏
【发布时间】:2019-08-07 03:26:16
【问题描述】:

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

Here's an example sandbox。沙盒非常特定于我如何使用相关组件。

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

【问题讨论】:

    标签: reactjs material-ui


    【解决方案1】:

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

    这是您在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 组件之外定义的,类似于您的代码的固定版本现在的结构。

    【讨论】:

    • 这是一个非常有用的答案。谢谢。
    【解决方案2】:

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

    还有一个解决办法: 将父组件定义为类组件(不是功能组件)。

    我的问题是我像这样调用“行”函数:

     <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}) => {
        ...
      }
    

    我使用itemData 属性访问renderListItem 函数内的nodes 数组

    【讨论】:

      猜你喜欢
      • 2020-04-26
      • 1970-01-01
      • 2020-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多