我怎么告诉砌体组件它的细胞已经改变了它们的高度?

Mar*_*enk 3 react-virtualized

我有一个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>
    );
}
Run Code Online (Sandbox Code Playgroud)

resetMasonry在组件的高度状态发生变化时调用.我已经从几个stackoverflow答案和其他资源中删除了当前代码,甚至查看了源代码,但没有任何效果.我注意到我没有告诉cellMeasurerCache或其他关于高度变化的事情,所以我真的不应该期待它能够工作,但似乎没有办法在那里获取信息,甚至没有通过实例化新的CellMeasurerCache.

顺便说一句,如果我在其中更改columnWidth cellPositioner.reset,则Masonry组件会相应更新,当然.

有人知道我缺少什么让它适应高度变化吗?谢谢!

bva*_*ghn 7

如果您的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()
})
Run Code Online (Sandbox Code Playgroud)

您可以通过更改列宽来查看RV网站Masonry上更改列高的组件演示.该演示的源代码也可以在GitHub repo中找到.

根据你所描述的,我不建议使用Masonry.我实际上只是建议使用List类似于我在此示例中的方式:http://plnkr.co/edit/zjCwNeRZ7XtmFp1PDBsc?p = preview

关键是根据可用宽度动态计算每行的项目数,然后给出List一个调整后的rowCount:

  const itemsPerRow = Math.floor(width / ITEM_SIZE);
  const rowCount = Math.ceil(ITEMS_COUNT / itemsPerRow);
Run Code Online (Sandbox Code Playgroud)