Next.js复选框筛选异常:Set.prototype.has()含元素却返回false
Next.js 复选框筛选功能修复方案
问题现状
学习Next.js时实现基于复选框的商品筛选功能,参考相关方案后,筛选返回的state.products始终为空。控制台显示筛选集合(Set)中存在目标元素(如Shop、Office),但Set.prototype.has()却返回false,导致无匹配结果。
核心错误原因
筛选逻辑中使用forEach遍历拆分后的属性值是关键问题:
product.attributes.propertySubType.split(" ").forEach(element => { if((element.match(/Shop|Office|Showroom/))!=null) return element })
forEach方法没有返回值,无论内部返回什么,最终都会返回undefined。这意味着你实际在执行filters.has(undefined),而你的筛选集合中不存在undefined,因此所有商品都被过滤掉,结果为空。
修复后的代码
筛选函数修改
将forEach替换为some(用于判断是否存在符合条件的元素),同时优化状态更新的依赖项:
const [state, setState] = useState({ products: cspaces, filters: new Set(), }) const handleFilterChange = useCallback(event => { setState(previousState => { const filters = new Set(previousState.filters) // 根据复选框状态更新筛选集合 if (event.target.checked) { filters.add(event.target.value) } else { filters.delete(event.target.value) } let products = cspaces // 有筛选条件时执行过滤 if (filters.size > 0) { products = products.filter(product => { // 拆分属性值,判断是否有任意一个匹配筛选集合中的值 return product.attributes.propertySubType.split(" ").some(element => { const matchedType = element.match(/Shop|Office|Showroom/)?.[0] return matchedType && filters.has(matchedType) }) }) } return { filters, products } }) }, [cspaces]) // 依赖项添加cspaces,避免闭包导致的旧数据问题
关键优化点
- 使用
some替代forEach:some会在找到第一个符合条件的元素时立即返回true,更高效且能正确返回判断结果 - 明确提取匹配的类型:通过
match(/Shop|Office|Showroom/)?.[0]获取具体的匹配字符串,避免多余字符干扰 - 修正useCallback依赖:添加
cspaces作为依赖,确保状态更新时使用最新的商品数据
复选框代码(无需修改,仅确认一致性)
确保复选框的value与你要匹配的分类文本完全一致(如"Shop"、"Office"):
{data.propertytype.items.map((tag, index) => ( <li key={tag.value}> <Form.Check type="checkbox" id={tag.value} name={tag.value} label={tag.label} value={tag.label} onChange={handleFilterChange} /> </li> ))}
筛选结果渲染(无需修改)
{state.products.map((filteredListItems, id) => ( <Col key={id} sm="6" lg="4" className="mb-5 hover-animate" > <CardCspace data={filteredListItems} /> </Col> ))}
内容的提问来源于stack exchange,提问作者Geethika
相关产品推荐
相关产品推荐

