如何使用反应虚拟化制作具有响应式列数的列表/网格?

4 typescript react-virtualized

我有一个“卡片”组件,它以设定的方式呈现对象的数据。

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

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

我希望列数能够响应地改变。例如,如果父组件对于 3 列来说变得太窄,那么它应该改为使用 2 列。

从概念上讲,这是相当容易实现的。组件尺寸是众所周知的,因此不需要即时尺寸测量,并且计算适合列表宽度的组件数量也很简单,列表宽度给出了列数。

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

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

砖石布局似乎提供了我们想要的,但我无法让它工作”。

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

我使用了 afixedWidth作为CellMeasurerCachethe 的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}
            />
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

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

我不知道为什么它只呈现一列,而不是其中两列。

.ReactVirtualized__Masonry元素的高度为 1000px,在Masonry组件上设置,但它的子元素ReactVirtualized__Masonry__innerScrollContainer的高度为335px;,我不知道为什么,但它“切断”了可见的卡片。

HTML 截图

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

Masonry 是错误的选择吗?内部还有更好的选择吗react-virtualized

我是否想用锤子拧钉子,我应该从头开始做一些东西吗?

bva*_*ghn 9

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

所有卡片的宽度和高度都相同吗?如果是这样,则不需要Masonry该组件。它适用于 pinterest.com 等用例。(实际上是我专门为他们建造的。)

您所描述的内容不太复杂,因此可以以更有效的方式完成。这是一个用于List构建您所描述的 UI 类型的示例。

如果每张卡的尺寸不同,则应Masonry使用正确的组件。

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

不幸的是这是真的。我Masonry专门为 Pinterest 的用例构建了该组件,并尝试尽可能地优化它,使其变得更快而不是通用