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

React-Select下拉选项选择卡顿问题求助

解决react-select选择选项卡顿的问题

首先先修正你代码里的语法错误:getItems函数的.then回调后缺少闭合的括号和大括号,同时优化异步写法(避免async/await和.then混用),正确写法如下:

const getItems = async () => {
  try {
    const response = await Axios.get(`http://127.0.0.1:5000/items/available/${myItem}`);
    const items = response.data.map((item) => ({ label: item.name, value: item.id }));
    setItemOptions(items);
  } catch (error) {
    console.error('获取数据失败:', error);
  }
};

接下来针对卡顿问题,给你几个实用的优化方案:

1. 启用虚拟滚动(针对数据量大的核心优化)

如果你的itemOptions数量较多(比如几百上千条),react-select默认会渲染所有选项,这是卡顿的主要原因。通过虚拟滚动可以只渲染可视区域的选项,大幅提升性能。

先安装依赖:

npm install react-window

然后修改Select组件代码,自定义虚拟滚动的选项列表:

import { FixedSizeList as List } from 'react-window';

// 自定义虚拟滚动的单个选项组件
const VirtualizedOption = ({ children, innerRef, style }) => (
  <div ref={innerRef} style={{ ...style, top: style.top + 1 }}>
    {children}
  </div>
);

// 自定义虚拟滚动的菜单容器
const VirtualizedMenu = ({ children, options, styles, innerRef }) => {
  const menuHeight = 300;
  const itemHeight = 35;

  return (
    <div ref={innerRef} style={styles.menu}>
      <List
        height={menuHeight}
        itemCount={options.length}
        itemSize={itemHeight}
        width="100%"
      >
        {({ index, style }) => (
          <VirtualizedOption style={style}>
            {children[index]}
          </VirtualizedOption>
        )}
      </List>
    </div>
  );
};

// 使用虚拟滚动的Select组件
<Select
  isMulti
  options={itemOptions}
  filterOption={createFilter({ ignoreAccents: false })}
  components={{ Menu: VirtualizedMenu }}
/>

2. 缓存filter函数,避免不必要重渲染

你现在每次组件渲染都会调用createFilter生成新函数,会触发Select组件的无意义重渲染。用useMemo缓存这个函数:

import { useMemo } from 'react';
import { createFilter } from 'react-select';

// 在组件内部缓存filter函数
const customFilter = useMemo(() => {
  return createFilter({ ignoreAccents: false });
}, []);

// 调用Select时使用缓存后的函数
<Select
  isMulti
  options={itemOptions}
  filterOption={customFilter}
/>

(注:新版react-select中filter属性已被filterOption替代,无需重复设置)

3. 优化数据触发逻辑

确保getItems只在必要时调用,比如myItem变化时才发起请求,用useEffect包裹:

import { useEffect } from 'react';

useEffect(() => {
  if (myItem) {
    getItems();
  }
}, [myItem]); // 仅当myItem变化时重新获取数据

4. 给选项添加唯一标识(可选)

如果你的选项value存在重复风险,或者想让渲染更稳妥,可以在映射数据时给每个选项添加key属性:

const items = response.data.map((item) => ({ 
  label: item.name, 
  value: item.id,
  key: item.id // 添加唯一key
}));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 21:25:14