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

React搜索输入时如何实现数组实时模糊匹配过滤

问题根源

当前搜索逻辑使用===做严格全等匹配,要求输入内容和职位名称完全一致才会返回结果,无法支持关键词片段搜索。另外代码存在一处逻辑疏漏:过滤后的结果存储在filtered状态中,但渲染时遍历的是原始positions数组,过滤逻辑本身不会在页面生效。

实现方案

总共做3处调整即可实现需求:

  • 新增字符串归一化方法:统一将参与比对的文本转为小写,同时移除连字符、空格这类非字母数字的干扰字符,解决大小写不一致、缺省连字符无法匹配的问题
  • 将严格全等判断替换为模糊包含判断,支持关键词片段命中
  • 修复渲染逻辑,遍历过滤后的filtered数组展示结果

你提到的toLowerCase是实现大小写不敏感匹配的核心方法;some一般用于多字段匹配场景(比如需要同时支持搜索职位名、工作地点、职位类别时,判断任意字段命中就算匹配),单字段搜索场景不需要使用。

完整修改后代码

const Positions = ({ positions }: DataProps) => {
  const [selectLocation, setSelectLocation] = useState<any>('');
  const [selectJobType, setSelectJobType] = useState<any>('');
  const [filtered, setFiltered] = useState<any[]>([]);
  const [searchTerm, setSearchTerm] = useState<any>('');

  // 字符串归一化:统一转小写,移除连字符、空格等特殊干扰字符
  const normalizeStr = (str: string) => str.toLowerCase().replace(/[^a-z0-9]/g, '');

  useEffect(() => {
    if (positions.length > 0) {
      let newList = [...positions];
      if (searchTerm) {
        const normalizedKeyword = normalizeStr(searchTerm);
        // 替换原全等判断,归一化后做包含匹配
        newList = newList.filter((i) => normalizeStr(i.position).includes(normalizedKeyword));

        // 若需要支持多字段搜索(职位名/地点/类别任意命中即可),可改用some写法:
        // newList = newList.filter((i) => {
        //   return [i.position, i.location, i.category].some(field => 
        //     normalizeStr(field).includes(normalizedKeyword)
        //   )
        // })
      }

      if (selectJobType) {
        newList = newList.filter((i) => i.position === selectJobType);
      }

      if (selectLocation) {
        newList = newList.filter((i) => i.location === selectLocation);
      }

      setFiltered(newList);
    }
  }, [positions, searchTerm, selectJobType, selectLocation]);

  return (
    <>
      <div>
        <input
          type='search'
          placeholder='Search'
          onChange={(e) => setSearchTerm(e.target.value)}
        />

        <Select
          defaultValue={selectLocation}
          onChange={setSelectLocation}
          options={locations}
          instanceId={'1'}
          placeholder='Location'
        />
      </div>

      <Select
        defaultValue={selectJobType}
        onChange={setSelectJobType}
        options={jobs}
        placeholder='Job Type'
        instanceId={'2'}
      />

      {/* 替换原positions遍历,改为渲染过滤后的结果 */}
      {filtered?.map((position: any) => (
        <SinglePosition
          category={position.category}
          type={position.type}
          location={position.location}
          position={position.position}
          key={position._id}
        />
      ))}
    </>
  );
};

匹配效果

修改后输入back、backend、Back-end这类片段,都会命中Back-End Developer结果,不需要完整输入全量字符串,缺省连字符、大小写混用都不会影响匹配结果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 03:36:25