如何使用React JS实现产品列表的动态筛选功能
实现方案
核心筛选逻辑
首先实现通用筛选函数,无需硬编码任何筛选字段的判断逻辑,新增筛选字段时自动适配,符合你无需写if else的要求:
/** * 通用产品筛选方法 * @param {Array} products 原始产品列表 * @param {Object} filterFields 筛选条件对象,结构和你定义的一致 * @returns {Array} 筛选后的产品列表 */ const filterProducts = (products, filterFields) => { return products.filter(product => { // 所有筛选条件都满足才保留当前产品 return Object.entries(filterFields).every(([field, allowedValues]) => { // 可根据业务需求调整值的格式化规则,这里处理了大小写、空格兼容 const productVal = product[field]?.toString().toLowerCase().replaceAll(' ', '') const formattedAllowed = allowedValues.map(val => val.toLowerCase().replaceAll(' ', '')) return formattedAllowed.includes(productVal) }) }) }
React 组件完整实现
通过状态管理动态维护筛选条件,配合动态渲染的复选框实现可扩展的筛选功能:
第一步:定义筛选项配置(可任意扩展)
新增筛选字段只需修改该配置,无需修改业务逻辑:
const filterConfig = [ { key: 'brand', label: '品牌', options: [ { value: 'Ray Band', label: 'Ray Band' }, { value: 'Okaley', label: 'Okaley' }, { value: 'Dior', label: 'Dior' } ] }, { key: 'size', label: '尺码', options: [ { value: 'medium', label: '中码' }, { value: 'large', label: '大码' }, { value: 'free size', label: '均码' } ] } ]
第二步:组件代码
import { useState, useMemo } from 'react' const ProductFilter = ({ originalProducts }) => { // 存储筛选条件 const [filterFields, setFilterFields] = useState({}) // 缓存筛选结果,避免不必要的重复计算 const filteredProducts = useMemo(() => { if (Object.keys(filterFields).length === 0) return originalProducts return filterProducts(originalProducts, filterFields) }, [originalProducts, filterFields]) // 复选框勾选状态变更处理 const handleCheck = (fieldKey, optionVal, isChecked) => { setFilterFields(prev => { const currentVals = prev[fieldKey] || [] const newVals = isChecked ? [...currentVals, optionVal] : currentVals.filter(item => item !== optionVal) // 字段无选中值时移除该筛选条件 if (newVals.length === 0) { const { [fieldKey]: _, ...rest } = prev return rest } return { ...prev, [fieldKey]: newVals } }) } return ( <div style={{ padding: '20px' }}> {/* 筛选区 */} <div className="filter-section"> {filterConfig.map(filter => ( <div key={filter.key} style={{ marginBottom: '16px' }}> <h4>{filter.label}</h4> {filter.options.map(option => ( <label key={option.value} style={{ display: 'block', margin: '4px 0' }}> <input type="checkbox" checked={filterFields[filter.key]?.includes(option.value) || false} onChange={e => handleCheck(filter.key, option.value, e.target.checked)} /> <span style={{ marginLeft: '6px' }}>{option.label}</span> </label> ))} </div> ))} </div> {/* 产品展示区 */} <div className="product-list"> {filteredProducts.map((product, idx) => ( <div key={idx} style={{ border: '1px solid #eee', padding: '12px', marginBottom: '8px' }}> <p>品牌:{product.brand}</p> <p>尺码:{product.size}</p> <p>价格:¥{product.price}</p> </div> ))} </div> </div> ) }
扩展说明
- 同字段下的多个选中值为或的关系,不同字段之间为且的关系,完全匹配你的需求
- 后续新增价格、分类等筛选维度,只需在
filterConfig中添加对应配置即可自动生效 - 不需要嵌套循环,代码可读性和性能都优于forEach嵌套的实现
内容的提问来源于stack exchange,提问作者Nyi Nyi Hmue Aung
相关产品推荐
相关产品推荐

