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

如何实现react-window Grid首列与表头固定及滚动同步?

修复react-window Grid组件的首列滚动同步问题

针对你遇到的两个问题,以下是具体修复方案:

问题1:首列无法随Grid向下滚动

场景1:首列为独立滚动容器(如单独的FixedSizeList)

通过监听滚动事件同步垂直滚动位置,实现双向联动:

  1. 给首列列表和Grid分别添加ref,获取滚动容器实例
  2. 在各自的onScroll事件中,同步对方的scrollTop值

示例代码:

import { FixedSizeList as List, FixedSizeGrid as Grid } from 'react-window';
import { useRef } from 'react';

function DataTable({ records }) {
  const leftListRef = useRef(null);
  const gridRef = useRef(null);

  // 同步Grid到首列的垂直滚动
  const syncGridToLeftList = ({ scrollTop }) => {
    leftListRef.current?.scrollTo(scrollTop);
  };

  // 同步首列到Grid的垂直滚动
  const syncLeftListToGrid = ({ scrollTop }) => {
    gridRef.current?.scrollTo(scrollTop);
  };

  return (
    <div style={{ display: 'flex', gap: '2px' }}>
      {/* 首列:独立列表 */}
      <List
        ref={leftListRef}
        height={500}
        itemCount={records.length}
        itemSize={50}
        onScroll={syncLeftListToGrid}
        style={{ border: '1px solid #eee' }}
      >
        {({ index, style }) => (
          <div style={{ ...style, padding: '0 16px', lineHeight: '50px' }}>
            {records[index].id}
          </div>
        )}
      </List>

      {/* 右侧数据Grid */}
      <Grid
        ref={gridRef}
        height={500}
        width={800}
        columnCount={4}
        columnWidth={200}
        rowCount={records.length}
        rowHeight={50}
        onScroll={syncGridToLeftList}
        style={{ border: '1px solid #eee' }}
      >
        {({ columnIndex, rowIndex, style }) => (
          <div style={{ ...style, padding: '0 16px', lineHeight: '50px', borderLeft: '1px solid #eee' }}>
            {records[rowIndex][`column${columnIndex + 1}`]}
          </div>
        )}
      </Grid>
    </div>
  );
}

场景2:首列为Grid的一部分

给首列添加粘性定位,让它随垂直滚动同步,水平滚动时固定:

<Grid
  height={500}
  width={800}
  columnCount={5}
  columnWidth={160}
  rowCount={records.length}
  rowHeight={50}
>
  {({ columnIndex, rowIndex, style }) => {
    const isFirstColumn = columnIndex === 0;
    return (
      <div 
        style={{
          ...style,
          padding: '0 16px',
          lineHeight: '50px',
          ...(isFirstColumn ? {
            position: 'sticky',
            left: 0,
            backgroundColor: '#ffffff',
            zIndex: 1
          } : {})
        }}
      >
        {isFirstColumn ? records[rowIndex].id : records[rowIndex][`column${columnIndex}`]}
      </div>
    );
  }}
</Grid>

问题2:records的滚动行为与Grid保持一致

上述两种方案已解决滚动同步问题:

  • 分离式结构通过双向同步scrollTop,确保首列和Grid的垂直滚动完全一致
  • 内嵌式粘性列方案本身属于同一个Grid容器,滚动行为天然统一

注意事项

  • 确保首列和Grid的itemSize(行高)完全一致,避免滚动错位
  • 异步加载数据时,保证首列和Grid的数据源长度同步更新

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 10:53:14