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

Ant Design Select自定义:展示搜索值并支持新增选项

自定义Ant Design Select实现搜索值展示与新增选项

以下是符合需求的TS-React实现示例,核心通过onSearch监听输入值,配合dropdownRender自定义下拉内容,同时保留原生Select的过滤逻辑:

import React, { useState, useMemo } from 'react';
import { Select, Button } from 'antd';
import { PlusOutlined } from '@ant-design/icons';

interface OptionType {
  value: string;
  label: string;
}

const CustomSelect = () => {
  // 原始选项列表
  const [options, setOptions] = useState<OptionType[]>([
    { value: 'apple', label: '苹果' },
    { value: 'banana', label: '香蕉' },
    { value: 'orange', label: '橙子' },
  ]);
  // 记录用户输入的搜索值
  const [searchValue, setSearchValue] = useState('');
  // 过滤后的选项(保留原生Select的过滤逻辑)
  const filteredOptions = useMemo(() => {
    if (!searchValue) return options;
    return options.filter(opt => 
      opt.label.toLowerCase().includes(searchValue.toLowerCase())
    );
  }, [options, searchValue]);

  // 处理新增选项逻辑
  const handleAddOption = () => {
    const newOption: OptionType = {
      value: searchValue.toLowerCase(),
      label: searchValue,
    };
    // 避免重复添加
    if (!options.some(opt => opt.value === newOption.value)) {
      setOptions([...options, newOption]);
    }
    // 清空搜索框
    setSearchValue('');
  };

  return (
    <Select
      style={{ width: 200 }}
      placeholder="请选择或输入"
      showSearch
      onSearch={(value) => setSearchValue(value)}
      dropdownRender={(menu) => (
        <>
          {/* 当搜索值非空且不在现有选项中时,展示新增入口 */}
          {searchValue && !options.some(opt => opt.label.toLowerCase() === searchValue.toLowerCase()) && (
            <div style={{ padding: '8px 12px', borderBottom: '1px solid #f0f0f0' }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                <span>新增: {searchValue}</span>
                <Button 
                  type="text" 
                  icon={<PlusOutlined />} 
                  onClick={handleAddOption}
                  size="small"
                />
              </div>
            </div>
          )}
          {/* 展示过滤后的原生选项菜单 */}
          {menu}
        </>
      )}
    >
      {filteredOptions.map(opt => (
        <Select.Option key={opt.value} value={opt.value}>
          {opt.label}
        </Select.Option>
      ))}
    </Select>
  );
};

export default CustomSelect;

关键实现说明

  • 通过onSearch实时捕获用户输入的搜索值,存入状态searchValue
  • 利用useMemo生成过滤后的选项,保持原生Select的搜索过滤逻辑
  • 在dropdownRender中,先判断搜索值是否存在于现有选项:
    • 若不存在,则渲染新增选项入口,点击后将搜索值添加到选项列表
    • 再渲染原生的选项菜单,保证原有选择逻辑不受影响
  • 可根据需求调整新增选项的样式,比如修改间距、添加标识图标等,匹配预期设计

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 19:13:26