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
相关产品推荐
相关产品推荐

