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

如何在React.js中实现卡片组件的分类筛选功能?

React 实现工具卡片的分类筛选功能

核心思路

  • 用useState维护当前选中的分类标识,初始值设为代表“全部”的特殊值(比如'ALL')
  • 结合你已有的搜索关键词筛选逻辑,同时叠加分类筛选条件:当选中“全部”时不做分类过滤,否则只保留category匹配选中分类的卡片
  • 渲染分类选择控件时,默认添加“全部”选项,再遍历你的分类数组生成其他选项

完整代码示例

import { useState } from 'react';

// 模拟你的分类数据
const categories = [
  { id: 1, name: '开发工具' },
  { id: 2, name: '设计工具' },
  { id: 3, name: '协作工具' }
];

// 模拟你的工具卡片数据
const tools = [
  { id: 1, title: 'VS Code', description: '代码编辑器', category: '开发工具' },
  { id: 2, title: 'Figma', description: 'UI设计工具', category: '设计工具' },
  { id: 3, title: 'GitHub', description: '代码托管平台', category: '开发工具' },
  { id: 4, title: 'Slack', description: '团队协作工具', category: '协作工具' }
];

function ToolCard({ tool }) {
  return (
    <div style={{ border: '1px solid #eee', padding: '16px', margin: '8px', borderRadius: '4px' }}>
      <h3>{tool.title}</h3>
      <p>{tool.description}</p>
      <span style={{ fontSize: '12px', color: '#666' }}>{tool.category}</span>
    </div>
  );
}

function ToolGallery() {
  // 分类筛选状态,初始为全部
  const [selectedCategory, setSelectedCategory] = useState('ALL');
  // 已有的搜索关键词状态
  const [searchQuery, setSearchQuery] = useState('');

  // 组合搜索+分类的过滤逻辑
  const filteredTools = tools.filter(tool => {
    // 搜索匹配:标题或描述包含关键词(不区分大小写)
    const matchesSearch = tool.title.toLowerCase().includes(searchQuery.toLowerCase()) || 
                          tool.description.toLowerCase().includes(searchQuery.toLowerCase());
    // 分类匹配:选中全部则通过,否则匹配分类名称
    const matchesCategory = selectedCategory === 'ALL' || tool.category === selectedCategory;
    return matchesSearch && matchesCategory;
  });

  return (
    <div style={{ maxWidth: '1200px', margin: '0 auto', padding: '20px' }}>
      {/* 搜索框(你已有的组件) */}
      <input
        type="text"
        placeholder="搜索工具..."
        value={searchQuery}
        onChange={(e) => setSearchQuery(e.target.value)}
        style={{ padding: '8px', width: '300px', marginBottom: '16px' }}
      />

      {/* 分类选择下拉框 */}
      <select
        value={selectedCategory}
        onChange={(e) => setSelectedCategory(e.target.value)}
        style={{ padding: '8px', marginBottom: '16px' }}
      >
        <option value="ALL">全部</option>
        {categories.map(category => (
          <option key={category.id} value={category.name}>
            {category.name}
          </option>
        ))}
      </select>

      {/* 工具卡片列表 */}
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(250px, 1fr))', gap: '16px' }}>
        {filteredTools.map(tool => (
          <ToolCard key={tool.id} tool={tool} />
        ))}
      </div>
    </div>
  );
}

export default ToolGallery;

实用建议

  • 如果分类数量较多,下拉框可以换成标签按钮组(比如用button元素,选中时高亮),交互更直观
  • 把筛选逻辑抽成自定义Hook(比如useFilteredTools),方便在多个组件中复用,也让主组件更简洁:
    function useFilteredTools(tools, searchQuery, selectedCategory) {
      return useMemo(() => {
        return tools.filter(tool => {
          const matchesSearch = tool.title.toLowerCase().includes(searchQuery.toLowerCase()) || 
                                tool.description.toLowerCase().includes(searchQuery.toLowerCase());
          const matchesCategory = selectedCategory === 'ALL' || tool.category === selectedCategory;
          return matchesSearch && matchesCategory;
        });
      }, [tools, searchQuery, selectedCategory]);
    }
    
  • 当工具数据量较大时,用useMemo缓存过滤后的结果,避免每次渲染都重复执行过滤逻辑,提升性能
  • 如果分类的id和name是一一对应的,也可以用分类id作为选中值(比如把selectedCategory初始设为0代表全部),这样更严谨,避免分类名称重复的问题

内容的提问来源于stack exchange,提问作者Muhammad Hassan Saeed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 15:46:10