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

如何解决react-select搭配react-window时的下拉框高度问题?

react-select 搭配 react-window 的下拉框高度适配问题

问题场景

  • 下拉框仅包含2个选项时,下拉框高度远大于内容实际高度
  • 下拉选项从API动态获取,数量不固定
  • 需要为下拉框设置最大高度,超过时自动滚动

原代码

import Select from "react-select";
import { FixedSizeList as List } from "react-window";

const CustomMenuList = (props) => {
  const itemHeight = 35;
  const { options, children, maxHeight, getValue } = props;
  const [value] = getValue();
  const initialOffset = options.indexOf(value) * itemHeight;

  return (
    <div>
      <List
        style={{ height: "max-content", maxHeight: maxHeight }}
        height={maxHeight}
        itemCount={children.length}
        itemSize={itemHeight}
        initialScrollOffset={initialOffset}
      >
        {({ index, style }) => <div style={style}>{children[index]}</div>}
      </List>
    </div>
  );
};

const options = [
  { value: "chocolate", label: "Chocolate" },
  { value: "strawberry", label: "Strawberry" }
];

const ReactSelect = () => {
  return (
    <>
      <Select
        options={options}
        components={{
          MenuList: CustomMenuList
        }}
      />
    </>
  );
};

export default ReactSelect;

解决方案

修改CustomMenuList组件,动态计算下拉框的实际高度——取「所有选项总高度」和「设置的最大高度」中的较小值,既保证选项少的时候下拉框贴合内容,又能在选项过多时触发滚动。

修改后的代码:

import Select from "react-select";
import { FixedSizeList as List } from "react-window";

const CustomMenuList = (props) => {
  const itemHeight = 35;
  const { options, children, maxHeight = 200, getValue } = props; // 默认最大高度200px,可按需调整
  const [value] = getValue();
  const initialOffset = options.indexOf(value) * itemHeight;
  
  // 动态计算实际高度:选项总高度 vs 最大高度,取较小值
  const actualHeight = Math.min(children.length * itemHeight, maxHeight);

  return (
    <div>
      <List
        style={{ height: actualHeight, maxHeight: maxHeight }}
        height={actualHeight}
        itemCount={children.length}
        itemSize={itemHeight}
        initialScrollOffset={initialOffset}
      >
        {({ index, style }) => <div style={style}>{children[index]}</div>}
      </List>
    </div>
  );
};

const options = [
  { value: "chocolate", label: "Chocolate" },
  { value: "strawberry", label: "Strawberry" }
];

const ReactSelect = () => {
  return (
    <>
      <Select
        options={options}
        components={{
          MenuList: CustomMenuList
        }}
        // 可通过menuProps传递自定义maxHeight
        menuProps={{ maxHeight: 175 }}
      />
    </>
  );
};

export default ReactSelect;

修改说明

  1. 动态高度计算:通过Math.min(children.length * itemHeight, maxHeight)计算实际渲染高度,当选项总高度小于最大高度时,下拉框高度贴合内容;超过时限制在最大高度并显示滚动条
  2. 默认最大高度:给maxHeight设置默认值,避免未传入时出现异常
  3. 自定义最大高度:可以通过Select组件的menuProps传递自定义的maxHeight,灵活适配不同场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 00:00:56