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

React多类别商品过滤:如何实现多类别同时筛选?

实现React筛选器的多类别多选过滤

现有代码

const [product, setProduct] = useState([]);
const [filters, setFilters] = useState({
    category: '',
    brand: '',
    type: '',
  });
const displayProduct = product
.filter(prod =>
    prod.category.includes(filters.category) &&
    prod.brand.includes(filters.brand) &&
    prod.type.includes(filters.type)
  )
.map(product => {
    return(
        <div className='imageContainer ' key={product.id}>
            <img src={PopularOne} className="image"/>
            <div className='productName'>
            <Link style={{ textDecoration:'none' }} to="/productsDetails" state={{ product:product }}>{product.productName}</Link>
            </div>
            <div className='productPrice'>
            <h3 >RM{product.productPrice}</h3>
            </div>
        </div>   
    )
})
<input type="checkbox"  onClick={() => {setFilters({...filters,category: 'abc',})}}/><label>abc</label><br/>
<input type="checkbox"  onClick={() => {setFilters({...filters,category: 'test',})}}/><label>test</label>

需求说明

现有一个可按Category、Brand、Type过滤商品的React筛选器,目前仅能单次选择一个类别进行过滤,希望实现可多选多个类别并同时过滤的效果。


解决方案

要实现多选类别过滤,核心是把存储选中类别的变量从字符串改成数组,同时调整复选框逻辑和过滤规则:

1. 修改状态结构

将filters中的category改为数组(如果brand和type也需要支持多选,可参照此修改),用来存储多个选中的类别:

const [filters, setFilters] = useState({
    category: [], // 数组存储多个选中类别
    brand: '',
    type: '',
  });

2. 调整复选框点击逻辑

封装复用的类别选择函数,点击时判断当前类别是否已选中,已选中则移除,未选中则添加:

// 处理类别选中/取消的复用函数
const handleCategoryToggle = (categoryName) => {
  setFilters(prev => ({
    ...prev,
    category: prev.category.includes(categoryName)
      ? prev.category.filter(item => item !== categoryName) // 移除已选类别
      : [...prev.category, categoryName] // 添加新类别
  }));
};

// 更新复选框的点击绑定
<input type="checkbox" onClick={() => handleCategoryToggle('abc')}/><label>abc</label><br/>
<input type="checkbox" onClick={() => handleCategoryToggle('test')}/><label>test</label>

3. 更新过滤逻辑

修改过滤规则:如果选中类别数组为空,则不进行类别过滤;如果有选中项,判断商品类别是否在选中列表中:

const displayProduct = product
.filter(prod => {
  // 类别过滤:空数组则显示所有,否则匹配选中的类别
  const categoryMatch = filters.category.length === 0 
    ? true 
    : filters.category.includes(prod.category);
  
  // 品牌和类型保持原有逻辑,如需多选可参照类别修改
  const brandMatch = filters.brand === '' ? true : prod.brand.includes(filters.brand);
  const typeMatch = filters.type === '' ? true : prod.type.includes(filters.type);
  
  return categoryMatch && brandMatch && typeMatch;
})
.map(product => {
    return(
        <div className='imageContainer ' key={product.id}>
            <img src={PopularOne} className="image"/>
            <div className='productName'>
            <Link style={{ textDecoration:'none' }} to="/productsDetails" state={{ product:product }}>{product.productName}</Link>
            </div>
            <div className='productPrice'>
            <h3 >RM{product.productPrice}</h3>
            </div>
        </div>   
    )
})

可选优化:同步复选框选中状态

让复选框的选中状态和当前筛选状态保持一致,提升用户体验:

<input 
  type="checkbox" 
  checked={filters.category.includes('abc')}
  onClick={() => handleCategoryToggle('abc')}
/><label>abc</label><br/>
<input 
  type="checkbox" 
  checked={filters.category.includes('test')}
  onClick={() => handleCategoryToggle('test')}
/><label>test</label>

如果brand和type也需要支持多选,完全可以参照上述步骤修改对应的状态和逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 17:40:17