Недавно я использовал react-virtualized
List
, чтобы отображать строки изображений с фиксированной высотой, карты с переменной шириной, и он отлично работал.
List
rowRenderer
использует массив строк элементов карты изображений. То есть массив массивов реагирующих компонентов, как JSX.
См. Мою последнюю функцию, cardsRows
, поскольку я строю строки на основе ширины элементов и ширины экрана.
Вот как это выглядит:

Надеется, что это помогает!
Некоторые фрагменты моего кода:
import {AutoSizer, List} from 'react-virtualized';
...
updateDimensions() {
this.setState({
screenWidth: window.innerWidth,
});
}
componentDidMount() {
window.addEventListener("resize", this.updateDimensions);
}
componentDidUpdate(prevProps, prevState) {
const props = this.props;
const state = this.state;
if (JSON.stringify(props.imageDocs) !== JSON.stringify(prevProps.imageDocs) || state.screenWidth !== prevState.screenWidth)
this.setState({
cardsRows: cardsRows(props, state.screenWidth),
});
}
rowRenderer({key, index, style, isScrolling}) {
if (!this.state.cardsRows.length)
return '';
return (
<div id={index} title={this.state.cardsRows[index].length} key={key} style={style}>
{this.state.cardsRows[index]}
</div>
);
}
...
render() {
return (
<div style={styles.subMain}>
<AutoSizer>
{({height, width}) => (<List height={height}
rowCount={this.state.cardsRows.length}
rowHeight={164}
rowRenderer={this.rowRenderer}
width={width}
overscanRowCount={2}
/>
)}
</AutoSizer>
</div>
);
}
...
const cardsRows = (props, screenWidth) => {
const rows = [];
let rowCards = [];
let rowWidth = 0;
const distanceBetweenCards = 15;
for (const imageDoc of props.imageDocs) {
const imageWidth = getWidth(imageDoc);
if (rowWidth + distanceBetweenCards * 2 + imageWidth <= screenWidth) {
rowCards.push(cardElement(imageDoc));
rowWidth += distanceBetweenCards + imageWidth;
}
else {
rows.push(rowCards);
rowCards = [];
rowWidth = distanceBetweenCards;
}
}
if (rowCards.length) {
rows.push(rowCards);
}
return rows;
};
const styles = {
subMain: {
position: 'absolute',
display: 'block',
top: 0,
right: 0,
left: 0,
bottom: 0,
}
};
короткий nswer: вы не можете. Обходной путь, о котором я могу думать, - это расщепление всех ячеек в реальных строках, поэтому в строке 1 будут отображаться первые три изображения, а в строке 2 будут следующие четыре в вашем случае. Затем вы должны виртуализировать сами строки, а не отдельные ячейки. Это «по дизайну» ограничение виртуализированных списков вообще («список», а не «сетка»). –
Я согласен с тем, что сказал Серджиу. Чтобы добавить немного больше - верхняя коллекция, которую вы показали, действительно должна быть «Grid», а не «Компонента». «Grid» более эффективен и проще в использовании. Второй, который вы показываете, может быть «List», но вычисление количества строк будет немного сложнее. – brianvaughn
@brianvaughn Я предполагаю, что вы имеете в виду 'Collection', а не' Component'? В любом случае, я понимаю, о чем вы оба говорите. Думаю, я попробую «Сетка» для первой коллекции. Для второй коллекции я закончил использование [CassetteRocks/response-infin-scroller] (https://github.com/CassetteRocks/react-infinite-scroller). Когда у меня будет свободное время, я попробую снова реализовать вторую коллекцию, используя React Virtualized.Потому что мне очень нравится репо! :) Спасибо вам за ваш вклад. – Jooooooooohn