You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用react-virtualized的Grid创建自适应宽度的响应式卡片网格

实现react-virtualized Grid组件的响应式卡片网格(一维数据)

要实现类似CSS Grid minmax的响应式效果,核心是根据容器宽度动态计算列数和列宽,同时适配一维数据的渲染逻辑,以下是可行方案:

关键调整点

  • 动态计算列数:基于容器宽度和卡片最小宽度,算出当前能容纳的最大列数
  • 动态计算列宽:用容器宽度除以列数,让卡片自动填满剩余空间
  • 修正行数计算:一维数据需转换为二维网格的行数,即Math.ceil(总数据量 / 列数)
  • 调整单元格渲染逻辑:通过行号和列号计算对应一维数组的索引

完整实现代码

import _ from "lodash";
import { AutoSizer, Grid, WindowScroller } from "react-virtualized";

function GridExample() {
  const items = _.range(100).map((num) => ({ name: `Collection ${num}` }));
  const MIN_CARD_WIDTH = 100; // 卡片最小宽度
  const GUTTER = 8; // 卡片间距(可选)

  function renderItem({ columnIndex, key, rowIndex, style }) {
    // 计算一维数组对应的索引
    const itemIndex = rowIndex * columnCount + columnIndex;
    // 避免超出数据范围
    if (itemIndex >= items.length) return null;
    
    return (
      <div 
        key={key} 
        style={{
          ...style,
          padding: GUTTER / 2,
          boxSizing: "border-box"
        }}
      >
        <div style={{
          width: "100%",
          height: "100%",
          border: "1px solid #eee",
          padding: 16,
          borderRadius: 4
        }}>
          {items[itemIndex].name}
        </div>
      </div>
    );
  }

  return (
    <WindowScroller>
      {({ height, isScrolling, onChildScroll, scrollTop }) => (
        <AutoSizer disableHeight>
          {({ width }) => {
            // 计算列数:减去间距后再计算,确保卡片间有空间
            const availableWidth = width - GUTTER;
            const columnCount = Math.max(1, Math.floor(availableWidth / (MIN_CARD_WIDTH + GUTTER)));
            // 计算列宽:均分可用宽度,包含间距
            const columnWidth = availableWidth / columnCount;
            
            // 计算总行数:向上取整确保所有数据都能渲染
            const rowCount = Math.ceil(items.length / columnCount);

            return (
              <Grid
                autoHeight
                columnCount={columnCount}
                columnWidth={columnWidth}
                width={width}
                height={height}
                rowCount={rowCount}
                rowHeight={50} // 可根据需求调整卡片高度
                cellRenderer={renderItem}
                isScrolling={isScrolling}
                scrollTop={scrollTop}
                onScroll={onChildScroll}
              />
            );
          }}
        </AutoSizer>
      )}
    </WindowScroller>
  );
}

代码说明

  1. 动态列计算:通过availableWidth减去总间距后,除以「最小卡片宽+单张卡片间距」得到列数,确保列数至少为1
  2. 间距处理:通过给单元格添加内边距实现卡片间距,同时设置boxSizing: border-box避免宽度溢出
  3. 数据索引转换:用rowIndex * columnCount + columnIndex将二维网格坐标转换为一维数组的索引,同时判断索引是否越界,避免渲染空单元格
  4. 行数修正:用Math.ceil(items.length / columnCount)确保所有数据都能被覆盖,不会因列数变化导致部分数据不渲染

内容的提问来源于stack exchange,提问作者goss

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 15:37:55