我如何告诉 Masonry 组件它的单元格已经改变了它们的高度?
How do I tell the Masonry component that its cells have changed their height?
我有一个 React 组件,它以网格模式显示一维项目列表。每个项目都具有相同的宽度和高度,并且位于三列内。可能有很多这样的东西,所以我决定使用 Masonry 组件试一试 react-virtualized,它似乎正是为这个用例而写的。它运作良好,但有一个警告:如果项目改变了它们的高度,我无法让 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
当组件的高度状态改变时调用。我从几个 Whosebug 答案和其他资源中收集了当前代码,甚至查看了源代码,但没有任何效果。我注意到我没有告诉 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()
})
您还可以在 RV site just by changing the column width. The source code for that demo is available in the GitHub repo 上看到一个 Masonry
组件的演示,它可以改变列的高度。
根据您的描述,我不建议使用 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);
我有一个 React 组件,它以网格模式显示一维项目列表。每个项目都具有相同的宽度和高度,并且位于三列内。可能有很多这样的东西,所以我决定使用 Masonry 组件试一试 react-virtualized,它似乎正是为这个用例而写的。它运作良好,但有一个警告:如果项目改变了它们的高度,我无法让 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
当组件的高度状态改变时调用。我从几个 Whosebug 答案和其他资源中收集了当前代码,甚至查看了源代码,但没有任何效果。我注意到我没有告诉 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()
})
您还可以在 RV site just by changing the column width. The source code for that demo is available in the GitHub repo 上看到一个 Masonry
组件的演示,它可以改变列的高度。
根据您的描述,我不建议使用 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);