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

React JS自定义筛选面板开发求助:多维度筛选实现思路

React 多维度按钮筛选面板实现思路

1. 定义筛选状态结构

用useState统一管理所有筛选维度的状态,把每个维度的选中值存到一个对象里,方便后续统一处理:

import { useState, useMemo } from 'react';

const ShirtFilter = () => {
  // 初始化筛选条件,默认无选中(可根据需求设默认值)
  const [filters, setFilters] = useState({
    priceRange: '', // 可选值:'0-100', '100-200', '200+'
    hasPattern: '', // 可选值:'yes', 'no'
    brand: '' // 可选值:'Nike', 'Adidas', 'Uniqlo'等
  });

  // 原始衬衫数据示例
  const shirtData = [
    { id: 1, name: '条纹衬衫', price: 99, hasPattern: true, brand: 'Uniqlo' },
    { id: 2, name: '纯色T恤', price: 159, hasPattern: false, brand: 'Nike' },
    { id: 3, name: '印花衬衫', price: 249, hasPattern: true, brand: 'Adidas' }
  ];

2. 实现筛选条件更新函数

写一个通用的状态更新函数,根据点击的按钮所属维度,精准更新对应状态值:

const handleFilterChange = (filterType, value) => {
    setFilters(prev => ({
      ...prev,
      [filterType]: value
    }));
  };

3. 渲染筛选按钮组

每个维度做独立按钮组,给选中状态的按钮加active类(需自行编写CSS样式标记选中态):

return (
    <div className="filter-panel">
      {/* 价格筛选组 */}
      <div className="filter-group">
        <h3>价格区间</h3>
        <button 
          className={filters.priceRange === '0-100' ? 'active' : ''}
          onClick={() => handleFilterChange('priceRange', '0-100')}
        >
          0-100元
        </button>
        <button 
          className={filters.priceRange === '100-200' ? 'active' : ''}
          onClick={() => handleFilterChange('priceRange', '100-200')}
        >
          100-200元
        </button>
        <button 
          className={filters.priceRange === '200+' ? 'active' : ''}
          onClick={() => handleFilterChange('priceRange', '200+')}
        >
          200元以上
        </button>
        <button 
          className={filters.priceRange === '' ? 'active' : ''}
          onClick={() => handleFilterChange('priceRange', '')}
        >
          全部
        </button>
      </div>

      {/* 有无图案筛选组 */}
      <div className="filter-group">
        <h3>有无图案</h3>
        <button 
          className={filters.hasPattern === 'yes' ? 'active' : ''}
          onClick={() => handleFilterChange('hasPattern', 'yes')}
        >
          有图案
        </button>
        <button 
          className={filters.hasPattern === 'no' ? 'active' : ''}
          onClick={() => handleFilterChange('hasPattern', 'no')}
        >
          无图案
        </button>
        <button 
          className={filters.hasPattern === '' ? 'active' : ''}
          onClick={() => handleFilterChange('hasPattern', '')}
        >
          全部
        </button>
      </div>

      {/* 品牌筛选组 */}
      <div className="filter-group">
        <h3>品牌</h3>
        <button 
          className={filters.brand === 'Uniqlo' ? 'active' : ''}
          onClick={() => handleFilterChange('brand', 'Uniqlo')}
        >
          Uniqlo
        </button>
        <button 
          className={filters.brand === 'Nike' ? 'active' : ''}
          onClick={() => handleFilterChange('brand', 'Nike')}
        >
          Nike
        </button>
        <button 
          className={filters.brand === 'Adidas' ? 'active' : ''}
          onClick={() => handleFilterChange('brand', 'Adidas')}
        >
          Adidas
        </button>
        <button 
          className={filters.brand === '' ? 'active' : ''}
          onClick={() => handleFilterChange('brand', '')}
        >
          全部
        </button>
      </div>

4. 实现核心筛选逻辑

用useMemo缓存筛选结果,避免每次渲染重复计算,仅当筛选条件或原始数据变化时重新过滤:

{/* 筛选结果展示 */}
      <div className="filtered-results">
        <h3>筛选结果</h3>
        {filteredShirts.map(shirt => (
          <div key={shirt.id} className="shirt-item">
            <p>{shirt.name}</p>
            <p>价格:{shirt.price}元</p>
            <p>图案:{shirt.hasPattern ? '有' : '无'}</p>
            <p>品牌:{shirt.brand}</p>
          </div>
        ))}
      </div>
    </div>
  );
};

export default ShirtFilter;

补充筛选函数的实现(放在组件内部return之前):

const filteredShirts = useMemo(() => {
  return shirtData.filter(shirt => {
    // 价格匹配逻辑
    const matchesPrice = !filters.priceRange || (
      (filters.priceRange === '0-100' && shirt.price <= 100) ||
      (filters.priceRange === '100-200' && shirt.price > 100 && shirt.price <= 200) ||
      (filters.priceRange === '200+' && shirt.price > 200)
    );

    // 图案匹配逻辑
    const matchesPattern = !filters.hasPattern || (
      (filters.hasPattern === 'yes' && shirt.hasPattern) ||
      (filters.hasPattern === 'no' && !shirt.hasPattern)
    );

    // 品牌匹配逻辑
    const matchesBrand = !filters.brand || shirt.brand === filters.brand;

    // 所有条件满足才保留
    return matchesPrice && matchesPattern && matchesBrand;
  });
}, [filters, shirtData]);

5. 可选优化点

  • 若需多选维度(比如同时选多个品牌),把对应状态改成数组(如brand: []),点击按钮时切换数组内的选中值,筛选逻辑改为shirt.brand.includes(选中品牌)或数组为空时全选。
  • 把每个筛选维度封装成独立组件(如PriceFilter.jsx),通过props传递选中值和更新函数,提升代码模块化程度。
  • 添加重置按钮,一键清空所有筛选条件:onClick={() => setFilters({priceRange: '', hasPattern: '', brand: ''})}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 19:10:32