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

React+TypeScript结合Formik实现自动补全输入框技术咨询

React + TypeScript + ASP.NET Core 自动补全输入框实现方案

前端(React + TypeScript)实现

1. 定义类型与状态

先通过TypeScript接口约束数据结构,明确业务字段:

// 匹配后端返回的数据结构
interface AutoCompleteItem {
  Project: string;
  Kommission: string;
  recipe: string;
  // 按需添加其他业务字段
}

// 组件内部状态管理
const [inputValue, setInputValue] = useState<string>('');
const [suggestions, setSuggestions] = useState<AutoCompleteItem[]>([]);
const [showSuggestions, setShowSuggestions] = useState<boolean>(false);
const [debounceTimer, setDebounceTimer] = useState<NodeJS.Timeout | null>(null);

2. 输入处理与数据匹配逻辑

根据数据量大小选择本地过滤或后端请求,这里两种方案都给出:

本地过滤版本(数据量小时用)

写一个多属性匹配的过滤函数,支持输入内容匹配任意字段:

const filterItems = (items: AutoCompleteItem[], searchText: string): AutoCompleteItem[] => {
  const lowerText = searchText.toLowerCase();
  return items.filter(item => 
    item.Project.toLowerCase().includes(lowerText) ||
    item.Kommission.toLowerCase().includes(lowerText) ||
    item.recipe.toLowerCase().includes(lowerText)
  );
};

// 输入框变化时的处理逻辑
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
  const value = e.target.value;
  setInputValue(value);
  
  if (!value) {
    setSuggestions([]);
    setShowSuggestions(false);
    return;
  }

  // 假设你有本地数据源localItems
  const filtered = filterItems(localItems, value);
  setSuggestions(filtered);
  setShowSuggestions(true);
};

后端请求版本(数据量大时用,带防抖)

添加防抖避免频繁调用接口,优化性能:

// 调用后端接口获取匹配数据
const fetchSuggestions = async (searchText: string) => {
  if (!searchText) return [];
  try {
    const response = await fetch(`/api/items?search=${encodeURIComponent(searchText)}`);
    const data: AutoCompleteItem[] = await response.json();
    return data;
  } catch (err) {
    console.error('获取建议列表失败:', err);
    return [];
  }
};

const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
  const value = e.target.value;
  setInputValue(value);

  // 清除上一次的防抖定时器
  if (debounceTimer) clearTimeout(debounceTimer);

  if (!value) {
    setSuggestions([]);
    setShowSuggestions(false);
    return;
  }

  // 300ms延迟后发起请求,避免频繁调用
  const timer = setTimeout(async () => {
    const data = await fetchSuggestions(value);
    setSuggestions(data);
    setShowSuggestions(true);
  }, 300);
  setDebounceTimer(timer);
};

3. 选中建议项的处理

点击建议项后,将输入框内容替换为对应项的Project值:

const handleSelectItem = (item: AutoCompleteItem) => {
  setInputValue(item.Project);
  setShowSuggestions(false);
};

4. 组件渲染

编写JSX结构,实现输入框+下拉建议列表的交互:

<div className="autocomplete-container">
  <input
    type="text"
    value={inputValue}
    onChange={handleInputChange}
    // 延迟隐藏列表,避免点击建议时直接失焦消失
    onBlur={() => setTimeout(() => setShowSuggestions(false), 200)}
    onFocus={() => inputValue && setShowSuggestions(true)}
    placeholder="输入项目、Kommission或配方..."
  />
  {showSuggestions && suggestions.length > 0 && (
    <ul className="suggestions-list">
      {suggestions.map((item, index) => (
        <li
          key={index}
          onClick={() => handleSelectItem(item)}
          className="suggestion-item"
        >
          <div>项目: {item.Project}</div>
          <div>Kommission: {item.Kommission}</div>
          <div>配方: {item.recipe}</div>
        </li>
      ))}
    </ul>
  )}
</div>

5. 基础样式(可选)

添加简单样式提升交互体验:

.autocomplete-container {
  position: relative;
  width: 350px;
}

.autocomplete-container input {
  width: 100%;
  padding: 10px;
  border: 1px solid #e0e0e0;
  border-radius: 4px;
  font-size: 14px;
}

.suggestions-list {
  position: absolute;
  top: calc(100% + 2px);
  left: 0;
  right: 0;
  border: 1px solid #e0e0e0;
  border-top: none;
  border-radius: 0 0 4px 4px;
  background: white;
  list-style: none;
  padding: 0;
  margin: 0;
  z-index: 1000;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

.suggestion-item {
  padding: 10px;
  cursor: pointer;
  border-bottom: 1px solid #f5f5f5;
}

.suggestion-item:hover {
  background-color: #fafafa;
}

.suggestion-item:last-child {
  border-bottom: none;
}

后端(ASP.NET Core)实现

1. 定义数据模型

和前端类型保持一致,确保数据结构匹配:

public class AutoCompleteItem
{
    public string Project { get; set; }
    public string Kommission { get; set; }
    public string Recipe { get; set; }
    // 对应前端的其他字段
}

2. 编写API接口

创建控制器实现模糊查询接口,支持多字段匹配:

[ApiController]
[Route("api/[controller]")]
public class ItemsController : ControllerBase
{
    private readonly IItemRepository _itemRepository;

    // 注入数据仓储或服务
    public ItemsController(IItemRepository itemRepository)
    {
        _itemRepository = itemRepository;
    }

    [HttpGet]
    public async Task<IActionResult> GetSuggestions([FromQuery] string search)
    {
        if (string.IsNullOrWhiteSpace(search))
        {
            return Ok(new List<AutoCompleteItem>());
        }

        var lowerSearch = search.ToLower();
        // 从数据库获取数据并过滤,直接在数据库层面做匹配优化性能
        var filteredItems = await _itemRepository.GetItemsAsync(item => 
            item.Project.ToLower().Contains(lowerSearch) ||
            item.Kommission.ToLower().Contains(lowerSearch) ||
            item.Recipe.ToLower().Contains(lowerSearch)
        );

        return Ok(filteredItems);
    }
}

3. 后端优化建议

  • 如果数据量较大,建议使用数据库的模糊查询(EF Core的Contains会转换为SQL的LIKE语句),避免内存过滤导致的性能问题。
  • 可添加分页参数,限制返回数据的数量,减少前端渲染压力。

关键注意点

  • 大小写不敏感:统一将输入内容和字段值转为小写(或大写)进行匹配,避免大小写导致的匹配遗漏。
  • 防抖处理:后端请求场景下必须加防抖,减少无效接口调用。
  • 焦点管理:输入框失焦时延迟隐藏列表,确保用户能选中建议项。
  • 类型安全:前后端数据类型保持一致,利用TypeScript的类型检查避免数据错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 01:45:31