【问题标题】:React Virtualized: Collection with cells that have the same fixed height but different widthsReact Virtualized:具有相同固定高度但不同宽度的单元格的集合
【发布时间】:2017-05-27 09:13:48
【问题描述】:

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

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

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

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

【问题讨论】:

  • 简短回答:你不能。我能想到的一种解决方法是将所有单元格拆分为实际行,因此在您的情况下,第 1 行将具有前三个图像,而第 2 行将具有接下来的四个图像。然后,您将虚拟化行本身,而不是单个单元格。这是一般虚拟化列表的“设计”限制(“列表”,而不是“网格”)。
  • 我同意 Sergiu 的说法。补充一点——你展示的顶级收藏确实应该是Grid,而不是ComponentGrid 更高效,使用更简单。您显示的第二个可能是List,但计算行数会有点棘手。
  • @brianvaughn 我猜你的意思是Collection而不是Component?不管怎样,我明白你们俩在说什么。我想我会在第一个系列中尝试Grid。对于第二个集合,我最终使用了CassetteRocks/react-infinite-scroller。当我有空闲时间时,我会尝试再次使用 React Virtualized 实现第二个集合。因为我真的很喜欢回购! :) 谢谢你们的意见。
  • 对不起,是的。输入错误。 :) 很高兴听到!

标签: css reactjs infinite-scroll react-virtualized


【解决方案1】:

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

我的List rowRenderer 使用一组图像卡元素行。也就是 React 组件的数组,如 JSX。

请参阅我的最终函数cardsRows,了解我如何根据元素宽度和屏幕宽度构建行。

它的外观如下:

希望这会有所帮助!

我的代码的一些 sn-ps:

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,
    }
};

【讨论】:

  • 有点过时了,但你是如何处理窗口调整大小事件的?
猜你喜欢
  • 2012-09-26
  • 2014-04-17
  • 1970-01-01
  • 1970-01-01
  • 2020-06-05
  • 2021-12-14
  • 2016-01-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多