React中如何对已过滤的对象数组实现二次过滤?
已分类数组的二次过滤问题修复
问题分析
你当前的代码存在几个关键问题导致侧边栏点击无效果:
- 侧边栏复选框与标签的关联属性错误,点击标签无法正确触发交互
- "See all"按钮未传入正确的恢复数据
- 未维护复选框的选中状态,既无视觉反馈也无法支持多选过滤
修复步骤
1. 修正侧边栏组件的基础错误
修复复选框与标签的关联逻辑,同时调整"See all"的触发逻辑:
function CategorySidebar({ menuItems, filterItems, resetFilter }) { return ( <div className="hidden md:flex md:basis-1/3 lg:basis-1/4 flex-col p-2 bg-white rounded-lg self-start sticky top-24"> <h1 className='font-medium mb-2'>Brand</h1> <ul> {menuItems?.map((brand) => ( <li className='mb-1' key={brand}> <label htmlFor={brand} className='flex items-center'> <input type="checkbox" id={brand} className='mr-1' onChange={(e) => filterItems(brand, e.target.checked)} /> {brand} </label> </li> ))} </ul> <ul> <li onClick={resetFilter}> <label className='flex items-center'> <input type="checkbox" className='mr-1' /> See all </label> </li> </ul> </div> ) }
2. 重构父组件的过滤逻辑(支持多选)
将单一品牌过滤改为维护选中品牌集合,实现多品牌同时过滤:
import { useState, useMemo } from 'react' // 按category过滤出初始数据 const filteredData = CardContents.filter(item => item.category === 'Keycaps') // 缓存所有品牌选项,避免重复计算 const menuItems = useMemo(() => [...new Set(filteredData.map(item => item.brand))], [filteredData]) // 维护选中的品牌集合 const [selectedBrands, setSelectedBrands] = useState([]) // 计算最终展示的商品数据 const item = useMemo(() => { // 无选中品牌时展示全部已分类商品 if (selectedBrands.length === 0) return filteredData // 有选中品牌时筛选对应商品 return filteredData.filter(item => selectedBrands.includes(item.brand)) }, [filteredData, selectedBrands]) // 处理品牌选择/取消逻辑 const filterItems = (brand, isChecked) => { setSelectedBrands(prev => { if (isChecked) { return [...prev, brand] } else { return prev.filter(b => b !== brand) } }) } // 重置过滤,回到全部商品状态 const resetFilter = () => { setSelectedBrands([]) }
3. 传递正确的props给侧边栏
在父组件中渲染侧边栏时,传入更新后的方法和数据:
<CategorySidebar menuItems={menuItems} filterItems={filterItems} resetFilter={resetFilter} />
关键优化点
- 使用
useMemo缓存计算结果,避免不必要的组件重渲染 - 支持多品牌同时过滤,提升交互灵活性
- 修复复选框与标签的关联问题,确保交互逻辑正常
- 拆分过滤与重置逻辑,代码结构更清晰
内容的提问来源于stack exchange,提问作者Daniel Oscar
相关产品推荐
相关产品推荐

