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

如何实现react-window FixedSizeList随视口滚动 隐藏组件自带滚动条

react-window绑定视口滚动、隐藏自带滚动条实现方案

核心逻辑

react-window默认以自身内部容器作为滚动载体,要实现视口滚动驱动列表渲染、隐藏组件自带滚动条,只需要做三件事:

  • 禁用组件内部容器的滚动能力,彻底隐藏自带滚动条
  • 在外层生成和列表总高度一致的占位块,让视口生成和原生页面一致长度的滚动条
  • 监听视口滚动事件,把滚动偏移同步给react-window实例,驱动它渲染对应可视区域的内容

实现代码

以下是基于你提供的示例修改的、可直接运行的FixedSizeList实现:

import { useRef, useEffect, useState } from 'react';
import { FixedSizeList } from 'react-window';

// 列表配置,统一抽离方便计算
const ITEM_SIZE = 35;
const ITEM_COUNT = 38;
const LIST_TOTAL_HEIGHT = ITEM_COUNT * ITEM_SIZE;

const Row = ({ index, style }) => <div style={style}>Row {index}</div>;

export default function ScrollBindList() {
  const listRef = useRef(null);
  const wrapperRef = useRef(null);
  const [listTop, setListTop] = useState(0);

  useEffect(() => {
    // 计算列表初始位置,页面加载、窗口尺寸变化时更新
    const updateListPosition = () => {
      if (!wrapperRef.current) return;
      const rect = wrapperRef.current.getBoundingClientRect();
      setListTop(rect.top + window.scrollY);
    };

    // 监听视口滚动,同步偏移给列表组件
    const handleWindowScroll = () => {
      if (!listRef.current) return;
      const scrollY = window.scrollY;
      // 计算列表实际需要滚动的偏移,做边界兜底
      let targetScrollTop = scrollY - listTop;
      targetScrollTop = Math.max(0, Math.min(targetScrollTop, LIST_TOTAL_HEIGHT - window.innerHeight));
      // 调用组件内置方法同步滚动位置
      listRef.current.scrollTo(targetScrollTop);
    };

    updateListPosition();
    window.addEventListener('scroll', handleWindowScroll, { passive: true });
    window.addEventListener('resize', updateListPosition);

    return () => {
      window.removeEventListener('scroll', handleWindowScroll);
      window.removeEventListener('resize', updateListPosition);
    };
  }, [listTop]);

  return (
    // 外层占位容器,高度等于列表总高度,撑出视口滚动条
    <div ref={wrapperRef} style={{ height: LIST_TOTAL_HEIGHT, position: 'relative' }}>
      {/* 粘性定位容器,把列表固定在视口可视区域 */}
      <div style={{ position: 'sticky', top: 0, height: '100vh' }}>
        <FixedSizeList
          ref={listRef}
          height={window.innerHeight}
          itemCount={ITEM_COUNT}
          itemSize={ITEM_SIZE}
          width="100%"
          // 隐藏自带滚动条
          style={{ overflow: 'hidden' }}
        >
          {Row}
        </FixedSizeList>
      </div>
    </div>
  );
}

FixedSizeGrid适配方法

Grid组件逻辑完全通用,只需要调整几个点:

  • 占位容器的宽高设置为列数*列宽、行数*行高,对应Grid的总内容尺寸
  • 如果需要绑定横向视口滚动,额外监听scrollX事件,调用实例的scrollTo({ scrollLeft, scrollTop })方法同步横向偏移
  • Grid组件本身的width设为视口宽度、height设为视口高度,同样加overflow: hidden样式

注意事项

  • 滚动事件必须加passive: true配置,避免阻塞主线程影响滚动流畅度
  • 如果页面有固定顶部导航,只需要把粘性容器的top值改为导航高度,列表高度改为calc(100vh - 导航高度),计算滚动偏移时同步减去导航高度即可
  • 不需要额外安装第三方依赖,纯原生API配合react-window自带的实例方法就能实现,性能和原生滚动基本一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 18:22:18