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

React中如何实现基于多标签数组的食谱数据过滤?

解决React食谱数据多标签过滤问题

修改后的过滤函数代码

const [cuisineInput, setCuisineInput] = useState("");
const [cuisineFilter, setCuisineFilter] = useState<Filter[]>([]);
const [filteredResults, setFilteredResults] = useState<any>([]); // 初始值设为空数组更合理

const filterDataByCuisine = useCallback(() => {
  // 无过滤标签时返回全部数据
  if (cuisineFilter.length === 0) {
    setFilteredResults(data?.hits || []);
    return;
  }

  // 提取过滤标签并统一转为小写,消除大小写差异
  const filterLabels = cuisineFilter.map(el => el.label.toLowerCase());
  
  const filteredData = data?.hits.filter(({ recipe }) => {
    // 将食谱的菜系类型转为小写数组,保证匹配一致性
    const recipeCuisines = recipe.cuisineType.map(cuisine => cuisine.toLowerCase());
    // 匹配逻辑:食谱包含任意一个过滤标签则保留("或"逻辑)
    return filterLabels.some(label => recipeCuisines.includes(label));
  }) || [];

  setFilteredResults(filteredData);
}, [cuisineFilter, data]);

关键修改说明

  • 空过滤处理:当cuisineFilter为空数组时,直接返回全部食谱数据,避免无标签时出现空结果。
  • 大小写统一:将过滤标签和食谱菜系都转为小写,解决大小写不匹配导致的过滤失效问题(比如"Italian"和"italian"视为同一菜系)。
  • 正确的多标签匹配逻辑:
    • 用Array.some()实现任意匹配:只要食谱包含过滤数组中的任意一个标签,就保留该食谱(这是多数场景的需求)。
    • 如果需要全部匹配(食谱必须包含所有过滤标签),只需把some()替换为every()即可:
      return filterLabels.every(label => recipeCuisines.includes(label));
      
  • 安全的可选链调用:用data?.hits替代强制非空断言data!.hits,避免data为null/undefined时抛出运行时错误。

额外优化建议

  • 把filteredResults的初始值从null改为空数组[],这样UI渲染时无需额外处理null的情况,更符合数组类型的使用习惯。
  • 可以给filteredResults添加更具体的类型注解,替代any,提升代码的类型安全性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 05:27:11