0

如果我可以使用 React Virtualized 的 Collection 组件来解决我的问题,我有点困惑。我将尝试描述我在做什么:

我在页面上使用 React Virtualized 来显示两个项目列表/集合。我已经完成了第一个具有相同宽度和高度的项目的集合:

单元格具有相同高度和宽度的集合

第一个集合非常简单且易于实施。现在我正在处理第二个集合,其中包含不同大小的图像。我希望单元格具有相同的高度但不同的宽度(当然取决于图像尺寸)。问题是行可能并不总是具有相同数量的单元格:

单元格具有相同高度但不同宽度的集合

这可以通过 React Virtualized 实现吗?如果是这样,我如何确定“cellSizeAndPositionGetter”中的位置?

4

1 回答 1

2

我最近用来react-virtualized List显示固定高度、可变宽度的图像卡行,效果很好。

List rowRenderer使用一组图像卡元素行。也就是说,一个 React 组件数组的数组,如 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,
    }
};
于 2017-01-22T21:35:28.497 回答