如何使用react-virtualized创建具有响应数量的列的列表/网格?

时间:2017-09-22 15:33:16

标签: typescript react-virtualized

我有一张"卡"以固定方式呈现对象数据的组件。

这些卡组件具有预定义的宽度和高度。

这些卡组件将以列表形式显示,我希望该列表能够利用可用的水平空间。

我希望响应式更改列数。例如如果父组件对于3列变得太窄,那么它应该使用2列。

从概念上讲,这很容易实现。元件尺寸是众所周知的,因此不需要实时尺寸测量,并且计算可以适合列表宽度的元件数量是微不足道的,这给出了数量列。

甚至可以选择使用display:flex并让它为您进行计算和布局。

我目前正在尝试使用react-virtualized来实现此响应列列表,因为我们已经在我们的应用中的其他情况下使用它了。它对虚拟化的支持也是一个强大的吸引力。

masonry布局似乎提供了我们想要的内容,但我无法让它工作"。

它需要CellMeasurerCache,需要固定宽度或固定高度。这是不幸的,因为我的组件具有固定的宽度和高度,因此测量是不必要的。

我对fixedWidth使用了CellMeasurerCache因为cellPositioner需要columnWidth,我认为它更好地认为'}不需要改变。

这是我的代码:

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { RouteComponentProps } from 'react-router-dom';
import { AutoSizer, Masonry, WindowScroller, CellMeasurer, CellMeasurerCache, MasonryCellProps, createMasonryCellPositioner } from 'react-virtualized';
import { Task } from '../../store/tasks';
import { TaskCard } from './taskcard';

type TaskCardListProps = {
    scrollElement?: any;
    tasks: Task[];
};

type TaskCardListState = {};

export class TaskCardList extends React.Component<TaskCardListProps, TaskCardListState> {
    public render() {
        const { tasks, scrollElement } = this.props;

        const cache = new CellMeasurerCache({            
            defaultHeight: 120,
            defaultWidth: 400,
            fixedWidth: true
        });

        const cellPositioner = createMasonryCellPositioner({
            cellMeasurerCache: cache,
            columnCount: 2,
            columnWidth: 400,
            spacer: 10
        });

        const cellRenderer = (props: MasonryCellProps) => {
            const { index, key, parent, style } = props;
            const task = tasks[index];

            return (
                <CellMeasurer cache={cache} index={index} key={key} parent={parent}>
                    <TaskCard { ...task } />
                </CellMeasurer>
            )
        };

        return (
            <Masonry
                autoHeight={false}
                cellCount={tasks.length}
                cellMeasurerCache={cache}
                cellPositioner={cellPositioner}
                cellRenderer={cellRenderer}
                height={1000}
                width={1500}
            />
        );
    }
}

我发现它确实渲染了卡片,但只有一列,并且砌体组件将height:auto;应用为卡片组件元素的样式!这意味着它超过了我的固定高度,导致卡片变形。

我不确定为什么它只渲染一个列,而不是其中两个。

.ReactVirtualized__Masonry元素的高度为1000像素,在Masonry组件上设置,但它的孩子ReactVirtualized__Masonry__innerScrollContainer的高度为335px; ,我不确定为什么,但它&#39; &#34;切断&#34;可以看到的卡片。

HTML Screenshot

我是否在做Masonry明显错误的事情?

Masonry是错误的选择,react-virtualized中有更好的选择吗?

我是不是想用锤子拧钉子,我应该从头开始制作东西吗?

1 个答案:

答案 0 :(得分:3)

  

这些卡组件具有预定义的宽度和高度。

所有卡片的宽度和高度是否相同?如果是这样,那么您就不需要Masonry组件。它适用于像pinterest.com这样的用例。 (我实际上专门为他们建造了它。)

您所描述的内容不那么复杂,因此可以更有效的方式完成。 Here's an example使用List来构建您所描述的UI。

如果每张卡的大小不同,则Masonry是正确使用的组件。

  

它需要CellMeasurerCache,需要固定宽度或固定高度。这是不幸的,因为我的组件具有固定的宽度和高度,因此测量是不必要的。

不幸的是,这是事实。我专门为Pinterest的用例构建了Masonry组件,并尝试尽可能快地优化它快速而不是泛型