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

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,避免闭包导致的旧数据问题

关键优化点

  1. 使用some替代forEach:some会在找到第一个符合条件的元素时立即返回true,更高效且能正确返回判断结果
  2. 明确提取匹配的类型:通过match(/Shop|Office|Showroom/)?.[0]获取具体的匹配字符串,避免多余字符干扰
  3. 修正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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 02:47:38