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

ReactJS中使用Redux Toolkit实现商品分类过滤问题求助

问题分析

当前分类过滤失效的核心问题:

  1. 产品数据存储错误:productSlice中直接将完整响应对象赋值给state.products,而非提取其中的产品数组,导致后续过滤逻辑无法正确遍历数据。
  2. 分类状态设计错误:filterSlice中category存储过滤后的产品数组,且用push操作导致状态变为二维数组,同时Home组件未使用该状态参与过滤。
  3. 过滤逻辑本末倒置:提前在前端过滤产品再存入Redux,无法和价格、评分等其他过滤条件结合,违背Redux存储过滤条件而非结果的设计原则。

修改步骤

1. 修复ProductSlice的数据存储

修改productSlice.js中fetchProducts的成功回调,正确提取产品数组:

// productSlice.js
.addCase(fetchProducts.fulfilled, (state, action) => {
  // 提取响应中的products数组,而非整个响应对象
  state.products = action.payload.products;
  state.status = STATUSES.IDLE;
})

同时修正Home组件的useSelector,正确获取产品数据:

// Home.js
const { products, status } = useSelector((state) => state.product); // 移除多余的.products

2. 重构FilterSlice的分类状态

将category改为存储选中的分类名称(支持单选,需多选可改为数组),并修正setCategoryFilter逻辑:

// filterSlice.js
initialState: {
  price: 1500,
  rating: 5,
  discount: 20,
  category: null // 初始无选中分类
},
reducers: {
  // ...其他reducer保持不变
  setCategoryFilter: (state, action) => {
    // 点击同一分类时取消选中(单选逻辑)
    state.category = state.category === action.payload ? null : action.payload;
  }
}

3. 修改Home组件的分类处理逻辑

删除提前过滤产品的代码,直接dispatch选中的分类名称:

// Home.js
const handleFilterCategory = (category) => {
  dispatch(setCategoryFilter(category));
};

在产品过滤链中添加分类过滤条件:

// Home.js
{searchProducts &&
  searchProducts
    ?.filter((product) => product.price <= price)
    ?.filter((product) => product.rating <= rating)
    ?.filter((product) => product.discountPercentage <= discount)
    ?.filter((product) => {
      // 未选中分类则返回所有产品,否则返回匹配分类的产品
      if (!category) return true;
      return product.category === category;
    })
    ?.map((product) => (
      <Products key={product.id} product={product} />
    ))}

4. 可选:支持多分类选择

若需要多选分类,修改filterSlice.js的初始状态和reducer:

// filterSlice.js
initialState: {
  // ...其他状态
  category: [] // 用数组存储选中的分类
},
reducers: {
  setCategoryFilter: (state, action) => {
    const selected = action.payload;
    // 切换选中状态:存在则移除,不存在则添加
    state.category = state.category.includes(selected)
      ? state.category.filter(c => c !== selected)
      : [...state.category, selected];
  }
}

同时修改Home中的分类过滤逻辑:

// Home.js
?.filter((product) => {
  // 无选中分类则返回所有,否则返回包含在选中分类中的产品
  if (category.length === 0) return true;
  return category.includes(product.category);
})

5. 同步SidebarFilterPanel逻辑

确保侧边栏过滤面板的分类点击事件也调用handleFilterCategory,和Filters组件保持一致:

// SidebarFilterPanel.js(示例)
{categories.map((category, index) => (
  <p
    className="cursor-pointer text-sm my-2 hover:text-orange-500"
    key={index}
    onClick={() => props.handleFilterCategory(category)}
  >
    {category}
  </p>
))}

验证效果

修改完成后,点击分类标签时:

  • Redux存储选中的分类条件
  • 产品列表会结合搜索、价格、评分、折扣和分类条件实时过滤
  • 单选模式下点击同一分类可取消选中,多选模式下可自由添加/移除分类

内容的提问来源于stack exchange,提问作者Pavitar Sharma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 13:50:26