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

如何滚动到react-virtualized渲染的指定React元素

解决react-virtualized虚拟列表滚动到指定未渲染项的方案

问题核心原因

  • 虚拟滚动的核心逻辑是仅渲染视口及周边少量列表项,未进入渲染范围的项不存在真实DOM节点,你给每个列表项绑定ref的方案自然拿不到未渲染项的DOM,调用getBoundingClientRect就会抛出空值错误。
  • 不需要手动通过DOM计算位置,react-virtualized的List组件本身暴露了跳转指定行的官方API,直接调用即可。

具体改造步骤

  1. 给List组件创建实例ref,不需要给每个列表项单独绑定ref
  2. 点击跳转按钮时,拿到目标项的索引,调用List实例的scrollToRow方法即可自动滚动到对应位置,组件内部会自动计算目标项的偏移量,哪怕该项未提前渲染也可以正常跳转。

改造后代码示例

import { useRef } from 'react';
import { WindowScroller, AutoSizer, List } from 'react-virtualized';

// 你自己定义的arr数据源
const arr = Array.from({length: 100}, (_, i) => ({id: i+1}));

export default function App() {
  // 给List组件创建ref
  const listRef = useRef(null);

  const onClick = (targetIndex) => {
    // 直接调用List实例的scrollToRow方法跳转到对应索引的项
    listRef.current?.scrollToRow(targetIndex);
    // 如果需要平滑滚动,且你的行高是固定值100,可以直接计算偏移量用原生滚动:
    // window.scrollTo({
    //   top: targetIndex * 100,
    //   behavior: 'smooth'
    // })
  };

  const items = arr.map((el) => ({
    id: el.id
  }));

  return (
    <div className="App">
      {items.map((item, index) => (
        <button onClick={() => onClick(index)} key={item.id}>Scroll to {item.id}</button>
      ))}

      <WindowScroller>
        {({ height, scrollTop, registerChild }) => (
          <div ref={registerChild}>
            <AutoSizer disableHeight>
              {({ width }) => (
                <List
                  ref={listRef} // 绑定ref到List组件
                  autoHeight
                  width={width}
                  height={height}
                  rowHeight={100}
                  rowRenderer={({ index }) => {
                    return (
                      <div
                        id={`item-${items[index].id}`}
                        key={items[index].id}
                        style={{height: 100, border: '1px solid #eee'}}
                      >
                        {items[index].id}
                      </div>
                    );
                  }}
                  scrollTop={scrollTop}
                  rowCount={items.length}
                  overscanRowCount={10} // 不需要设置过大的overscan,浪费性能
                  // 如果需要调整跳转后目标项的对齐方式,可以加scrollToAlignment参数,可选值为"start"/"center"/"end"/"auto"
                  scrollToAlignment="start"
                />
              )}
            </AutoSizer>
          </div>
        )}
      </WindowScroller>
    </div>
  );
}

补充说明

  • 如果你的行高是动态计算的,只要给List正确传入rowHeight的计算函数,scrollToRow依然可以正常工作,不需要手动处理偏移。
  • scrollToAlignment参数可以控制跳转后目标项在视口的对齐位置:start为顶部对齐,center为居中,end为底部对齐,auto为自动滚动到最近的位置。
  • 要平滑滚动效果的话,因为react-virtualized原生scrollToRow不支持smooth行为,固定行高场景直接按行高乘索引算偏移量调用原生window.scrollTo即可,动态行高场景可以自己通过List实例的getOffsetForRow方法获取目标偏移量再调用原生滚动。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 12:36:03