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

Next.js+TypeScript菜单分类筛选报错:TypeError: uniqueCategories.map is not a function

问题分析与解决方案

1. 修复uniqueCategories.map is not a function错误

这个错误的核心是uniqueCategories并非数组类型,大概率是Set转数组的操作出错,或是组件传参时类型不匹配导致的。

  • 正确完成Set转数组:
    必须用Array.from()或展开运算符[...set]把Set转为数组,示例:

    // 假设你的菜单数据是menuItems数组,每个item包含category字段
    const categorySet = new Set(menuItems.map(item => item.category));
    const uniqueCategories = Array.from(categorySet); // 或写成 [...categorySet]
    

    如果你直接把Set传给组件,Set本身没有map方法,必然触发报错。

  • 明确组件传参的类型定义:
    在CategoryButtons.tsx中,要严格定义接收的categories为字符串数组类型:

    // CategoryButtons.tsx
    interface CategoryButtonsProps {
      categories: string[];
      activeCategory: string;
      onCategoryChange: (category: string) => void;
    }
    
    export default function CategoryButtons({ categories, activeCategory, onCategoryChange }: CategoryButtonsProps) {
      return (
        <div className="category-buttons">
          {categories.map(category => (
            <button
              key={category}
              className={activeCategory === category ? 'active' : ''}
              onClick={() => onCategoryChange(category)}
            >
              {category}
            </button>
          ))}
        </div>
      );
    }
    

2. 解决TypeScript隐式any类型问题

  • 给菜单数据定义类型:
    先给菜单条目定义接口,从根源避免隐式any:
    // 比如在menuData.ts中
    export interface MenuItem {
      id: number;
      name: string;
      category: string;
      price: number;
      // 其他你需要的字段
    }
    
    export const menuItems: MenuItem[] = [
      // 你的菜单数据内容
    ];
    
  • 在page.tsx中使用类型确保安全:
    // page.tsx
    import { menuItems, MenuItem } from './menuData';
    import CategoryButtons from './CategoryButtons';
    import { useState } from 'react';
    
    export default function MenuPage() {
      const [activeCategory, setActiveCategory] = useState<string>('全部');
      const categorySet = new Set(menuItems.map(item => item.category));
      // 若需要"全部"选项,直接拼到数组最前面
      const uniqueCategories = ['全部', ...Array.from(categorySet)];
    
      // 菜单筛选逻辑
      const filteredMenu = activeCategory === '全部' 
        ? menuItems 
        : menuItems.filter(item => item.category === activeCategory);
    
      return (
        <div className="menu-page">
          <CategoryButtons 
            categories={uniqueCategories} 
            activeCategory={activeCategory} 
            onCategoryChange={setActiveCategory} 
          />
          <div className="menu-items">
            {filteredMenu.map(item => (
              <div key={item.id} className="menu-item">
                <h3>{item.name}</h3>
                <p>${item.price}</p>
              </div>
            ))}
          </div>
        </div>
      );
    }
    

3. 额外排查点

  • 打印uniqueCategories的类型和值:在page.tsx中用console.log(typeof uniqueCategories, uniqueCategories)确认它是数组而非Set或其他类型。
  • 检查菜单数据完整性:确保menuItems是合法数组,每个条目都有category字段,没有undefined的情况。
  • 异步数据处理:如果菜单数据是异步获取的,要在数据加载完成后再处理分类,比如加条件渲染:
    if (!menuItems) return <div>加载中...</div>;
    // 之后再处理uniqueCategories
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 02:27:45