gpt4 book ai didi

reactjs - React Virtualized 支持 flex-wrap/inline-block 样式的项目包装吗?

转载 作者:行者123 更新时间:2023-12-02 20:55:39 24 4
gpt4 key购买 nike

我目前有一个项目列表,例如 <ul><li/><li/>...</ul> ,每个样式都带有 display: inline-block 。这些项目不是固定的高度或宽度,尽管我可能可以将它们固定,并且每个项目都包含缩略图,有时还包含文本。

列表会随着窗口宽度的变化而自动换行,没有水平滚动条。例如,列表可能以 3 个项目开始,它们全部水平排列在窗口内的一行上:

| 1 2 3     |

然后添加更多项目,并且这些项目开始换行到第二行:

| 1 2 3 4 5 |
| 6 7 8 |

然后,如果窗口宽度发生变化,项目将重新换行:

| 1 2 3 4 5 6 7 |
| 8 |

当有数千个项目时,性能肯定会受到影响,所以我想看看是否有一种方法可以虚拟化列表。从我阅读的文档来看,React Virtualized 库目前似乎不支持此功能,但我想检查一下。 Collection组件看起来可能很接近,但我认为它不会随着窗口大小的调整而动态改变宽度或高度。

如果这种项目包装是可能的,是否有任何示例实现?

最佳答案

From my reading of the docs, it doesn't seem like this is currently supported by the React Virtualized library

我很想知道文档的哪一部分给了您这样的印象。您的用例听起来像是一个 react 虚拟化设备足以处理。 :)

The Collection component seems like it might be close

Collection 用于其他用途。也许these slides from a recent conference talk I gave可以稍微澄清一下。基本上,Collection 用于非线性数据(例如甘特图、Pinterest 布局等)。它更灵活,但会牺牲性能。您的用例听起来非常适合 List。 :)

更新答案

您可以使用ListAutoSizer 来完成此操作。您只需要使用可用宽度和项目高度来计算行数。不太复杂。 :)

Here is an example Plunker这是来源:

const { AutoSizer, List } = ReactVirtualized

const ITEMS_COUNT = 100
const ITEM_SIZE = 100

// Render your list
ReactDOM.render(
<AutoSizer>
{({ height, width }) => {
const itemsPerRow = Math.floor(width / ITEM_SIZE);
const rowCount = Math.ceil(ITEMS_COUNT / itemsPerRow);

return (
<List
className='List'
width={width}
height={height}
rowCount={rowCount}
rowHeight={ITEM_SIZE}
rowRenderer={
({ index, key, style }) => {
const items = [];
const convertedIndex = index * itemsPerRow;

for (let i = convertedIndex; i < convertedIndex + itemsPerRow; i++) {
items.push(
<div
className='Item'
key={i}
>
Item {i}
</div>
)
}

return (
<div
className='Row'
key={key}
style={style}
>
{items}
</div>
)
}
}
/>
)
}}
</AutoSizer>,
document.getElementById('example')
)

初步回答

这或多或少是我会做的:

export default class Example extends Component {
static propTypes = {
list: PropTypes.instanceOf(Immutable.List).isRequired
}

constructor (props, context) {
super(props, context)

this._rowRenderer = this._rowRenderer.bind(this)
this._rowRendererAdapter = this._rowRendererAdapter.bind(this)
}

shouldComponentUpdate (nextProps, nextState) {
return shallowCompare(this, nextProps, nextState)
}

render () {
const { list } = this.props

return (
<AutoSizer>
{({ height, width }) => (
<CellMeasurer
cellRenderer={this._rowRendererAdapter}
columnCount={1}
rowCount={list.size}
width={width}
>
{({ getRowHeight }) => (
<List
height={height}
rowCount={list.size}
rowHeight={getRowHeight}
rowRenderer={this._rowRenderer}
width={width}
/>
)}
</CellMeasurer>
)}
</AutoSizer>
)
}

_getDatum (index) {
const { list } = this.props

return list.get(index % list.size)
}

_rowRenderer ({ index, key, style }) {
const datum = this._getDatum(index)

return (
<div
key={key}
style={style}
>
{datum.name /* Or whatever */}
</div>
)
}

_rowRendererAdapter ({ rowIndex, ...rest }) {
return this._rowRenderer({
index: rowIndex,
...rest
})
}
}

关于reactjs - React Virtualized 支持 flex-wrap/inline-block 样式的项目包装吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40478198/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com