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

React中基于useState对象数组实现多关键词搜索过滤方案咨询

我来帮你搞定这个搜索功能!你的数据结构有点特殊——数组里每个元素是单个键的分类对象,所以过滤时要注意保留所有分类(哪怕对应结果为空),这也是你之前没成功的关键之一。下面是完整的解决方案:

import Card from '../components/Card'
import React, { useState, useEffect } from 'react';

export default function IndexPage({ data, search }) {
  const [filteredBySearch, setFilteredBySearch] = useState(data);

  useEffect(() => {
    // 搜索框为空时,直接恢复原始数据
    if (!search.trim()) {
      setFilteredBySearch(data);
      return;
    }

    // 处理搜索关键词:转小写、按任意空格拆分、过滤空字符串(兼容多空格输入)
    const searchKeywords = search.toLowerCase().split(/\s+/).filter(word => word);

    // 遍历每个分类,生成过滤后的新数据结构
    const filteredData = data.map(categoryObj => {
      // 获取当前分类的名称和对应的物品列表
      const categoryName = Object.keys(categoryObj)[0];
      const items = categoryObj[categoryName];

      // 过滤当前分类下的物品:只要匹配任意一个关键词就保留
      const filteredItems = items.filter(item => {
        // 把物品的所有可搜索字段(name/desc/allergens)转小写拼接,统一匹配
        const itemSearchText = `${item.name.toLowerCase()} ${item.desc.toLowerCase()} ${(item.allergens || '').toLowerCase()}`;
        // 检查是否有至少一个关键词出现在物品文本中
        return searchKeywords.some(keyword => itemSearchText.includes(keyword));
      });

      // 返回新的分类对象:保留原分类名,值为过滤后的物品数组(空数组也保留)
      return { [categoryName]: filteredItems };
    });

    setFilteredBySearch(filteredData);
  }, [search, data]); // 当搜索词或原始数据变化时,重新执行过滤

  return (
    <div className="main-content">
      <div className="card-container">
        {filteredBySearch.map((el, i) => {
          const categoryName = Object.keys(el)[0];
          return (
            <div key={i}>
              <h2 className="category" id={categoryName}>{categoryName}</h2>
              {el[categoryName].map((itm, index) => (
                <Card key={index} infoItem={itm} />
              ))}
            </div>
          );
        })}
      </div>
      <style jsx>{`...`}</style>
    </div>
  );
}

关键逻辑说明:

  1. 关键词处理:

    • 把搜索词转成小写,实现不区分大小写的搜索;
    • 用split(/\s+/)按任意数量空格拆分,避免多空格导致的空关键词问题。
  2. 分类保留规则:

    • 遍历原始数据的每个分类,不管过滤后物品是否为空,都会保留该分类对象(空数组也会保留),完全符合你给出的示例要求。
  3. 物品匹配规则:

    • 把物品的name、desc、allergens(兼容空值)字段拼接成统一的小写文本;
    • 用some判断物品是否匹配任意一个搜索关键词,满足你示例2中多关键词分别匹配不同物品的需求。
  4. 状态更新时机:

    • 通过useEffect监听search和原始data的变化,每次搜索词或数据源改变时自动重新过滤,保证状态和视图同步。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 08:32:52