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

react-select结合react-window时方向键滚动失效问题求助

react-select + react-window虚拟化后方向键滚动失效的解决方法

问题背景

使用react-window实现react-select下拉列表虚拟化后,无法通过上下方向键滚动列表,但移除虚拟化改用原生MenuList时,滚动功能完全正常。

问题代码

const MenuList = React.memo(({ options, children, maxHeight, getValue }) => {
  const [value] = getValue();
  const height = Math.min(children.length * 40, maxHeight);
  const initialOffset = options.indexOf(value) * 40;

  return (
    <List
      height={options.length >= 8 ? maxHeight : height}
      itemCount={children.length}
      itemSize={40}
      initialScrollOffset={initialOffset}
      width="100%"
    >
      {({ index, style }) => <div style={style}>{children[index]}</div>}
    </List>
  );
});

效果对比

  • 方向键滚动失效情况:方向键滚动失效
  • 正常滚动情况:正常滚动

问题原因

react-select的方向键导航依赖DOM中存在的选项元素管理焦点和滚动,但react-window虚拟化只会渲染视口内的选项。当方向键切换到未渲染的选项时,react-select找不到对应DOM元素触发滚动,同时react-window也未同步滚动位置到选中项。

解决代码

import { List } from 'react-window';
import React, { useRef, useEffect } from 'react';

const MenuList = React.memo(({ options, children, maxHeight, getValue, highlightedIndex }) => {
  const [value] = getValue();
  const height = Math.min(children.length * 40, maxHeight);
  const listRef = useRef(null);

  // 初始加载时滚动到已选中的选项
  useEffect(() => {
    const initialIndex = options.indexOf(value);
    if (initialIndex !== -1 && listRef.current) {
      listRef.current.scrollToItem(initialIndex);
    }
  }, [value, options]);

  // 高亮项变化时自动滚动到对应位置
  useEffect(() => {
    if (highlightedIndex !== null && listRef.current) {
      listRef.current.scrollToItem(highlightedIndex);
    }
  }, [highlightedIndex]);

  return (
    <List
      ref={listRef}
      height={options.length >= 8 ? maxHeight : height}
      itemCount={children.length}
      itemSize={40}
      width="100%"
    >
      {({ index, style }) => <div style={style}>{children[index]}</div>}
    </List>
  );
});

关键说明

  1. 接收highlightedIndex参数:react-select会自动将当前方向键选中的选项索引传递给MenuList,通过监听这个值的变化触发滚动。
  2. 用useRef控制react-window的List:通过ref获取List实例,调用内置的scrollToItem方法精准滚动到指定索引的选项。
  3. 双Effect处理场景:一个处理初始加载时的选中项滚动,另一个处理方向键切换高亮项时的实时滚动,确保选中项始终在视口内。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 04:07:39