react-virtualized - 我如何告诉 Masonry 组件它的单元格已经改变了它们的高度?

标签 react-virtualized

我有一个 react 组件,它以网格模式显示一维项目列表。每个项目具有相同的宽度和高度,并且它们位于三列内。其中可能有很多,所以我决定使用 Masonry 组件尝试 react 虚拟化,该组件似乎正是为这个用例编写的。它运作良好,但有一个警告:如果项目改变了它们的高度,我无法让 Masonry 注意到。

这是一个简化的示例:

constructor(props) {
    [...]
    this.cellMeasurerCache = new CellMeasurerCache({
        defaultHeight: this.state.height,
        fixedWidth: true,
    });

    this.cellPositioner = createMasonryCellPositioner({
        cellMeasurerCache: this.cellMeasurerCache,
        columnCount: 3,
        columnWidth: 250,
        spacer: 20,
    });
}

[...]

cellRenderer({ index, key, parent, style }) {
    return (
        <CellMeasurer
            cache={this.cellMeasurerCache}
            index={index}
            key={key}
            parent={parent}
        >
            <div style={style}>
                [...]
            </div>
        </CellMeasurer>
    );
}

resetMasonry() {
    this.cellMeasurerCache.clearAll();

    this.cellPositioner.reset({
        cache: this.cellMeasurerCache,
        columnCount: 3,
        columnWidth: 250,
        spacer: 20,
    });

    this.masonryRef.recomputeCellPositions();
}

render() {
    return (
        <AutoSizer>
            {({ height, width }) =>
                <Masonry
                    cellCount={this.state.list.length}
                    cellMeasurerCache={this.cellMeasurerCache}
                    cellPositioner={this.cellPositioner}
                    cellRenderer={this.cellRenderer}
                    height={height}
                    ref={this.setMasonryRef}
                    width={width}
                />
            }
        </AutoSizer>
    );
}
resetMasonry当组件的高度状态改变时调用。我已经从几个 stackoverflow 答案和其他资源中挖掘了当前代码,甚至查看了源代码,但没有任何效果。我注意到我没有告诉 cellMeasurerCache 或其他任何关于高度变化的信息,所以我真的不应该指望它起作用,但似乎没有办法在那里获取这些信息,甚至无法通过实例化新品 CellMeasurerCache .

顺便说一句,如果我在 cellPositioner.reset 内更改 columnWidth ,Masonry 组件相应更新,果然如此。

有谁知道我缺少什么才能让它改变高度?谢谢!

最佳答案

如果您的 Masonry单元格的大小发生变化,您需要清除 CellMeasurerCache 中的缓存大小然后确保 cellPositioner也知道新的尺寸。例如:

// Clear cached measurements since sizes have changed:
cellMeasurerCache.clearAll()

// Let your component know it needs to re-render
this.setState({...}, () => {
  // Assuming you're using the default createCellPositioner()
  // Let it know of any values that may have changed:
  cellPositioner.reset({
    columnCount,
    columnWidth,
    spacer
  })

  // Tell Masonry to discard any cached position data:
  masonryRef.clearCellPositions()
})

你可以看到一个 Masonry 的演示RV site 上列高发生变化的组件只需更改列宽即可。该演示的源代码可用 in the GitHub repo还。

不过,根据您的描述,我不建议使用 Masonry .我实际上只是建议使用 List与我在这个例子中的做法类似:http://plnkr.co/edit/zjCwNeRZ7XtmFp1PDBsc?p=preview

关键是根据可用宽度动态计算每行的item数,然后你给List调整后的 rowCount :
  const itemsPerRow = Math.floor(width / ITEM_SIZE);
  const rowCount = Math.ceil(ITEMS_COUNT / itemsPerRow);

关于react-virtualized - 我如何告诉 Masonry 组件它的单元格已经改变了它们的高度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44524350/

相关文章:

css - react 虚拟化 : Collection with cells that have the same fixed height but different widths

react-virtualized - InfiniteLoader 在loadMoreRows 完成后向上滚动时跳转

reactjs - 如何在虚拟化列表中使用选择下拉列表?

flexbox - 使用带有卡住页眉和页脚的 react 虚拟化窗口滚动器

react-virtualized - 将 Semantic UI React 与 React Virtualized 结合使用

javascript - 无法找出 react 虚拟化列表的重复行/项目问题

react-virtualized - 如何在 react 虚拟化表中呈现自定义 header

react 虚拟化和 react 自定义滚动条集成

reactjs - 如何在react-virtualized(CodeSandBox)中向表格添加水平滚动条

react-virtualized - React Virtualized - 表格示例 - 如何让它工作?