如何使用Redux Toolkit实现多条件联合筛选?
多条件联合筛选解决方案
你的问题根源在于每次筛选都直接基于原始products数组生成新的filteredItems,完全覆盖之前的筛选结果,导致无法叠加多个筛选条件。要实现联合筛选,需要先保存所有筛选参数,再基于这些参数重新计算最终的筛选结果。
步骤1:修改状态结构,保存所有筛选条件
把各个筛选维度的当前值存在状态里,而不是只存最终的筛选结果:
const initialState = { products: data, // 保存所有筛选条件的当前值,默认"All"表示不筛选该维度 filters: { category: "All", gender: "All", color: "All", brand: "All" } };
步骤2:更新Reducer,只修改筛选参数
每个筛选动作不再直接生成filteredItems,而是只更新对应维度的筛选值:
export const filterSlice = createSlice({ name: "filter", initialState, reducers: { setCategoryFilter: (state, action) => { state.filters.category = action.payload; }, setGenderFilter: (state, action) => { state.filters.gender = action.payload; }, setColorFilter: (state, action) => { state.filters.color = action.payload; }, setBrandFilter: (state, action) => { state.filters.brand = action.payload; } } }); // 导出action creators export const { setCategoryFilter, setGenderFilter, setColorFilter, setBrandFilter } = filterSlice.actions;
步骤3:用Selector计算最终筛选结果
使用Redux Toolkit内置的createSelector(来自Reselect库),基于原始数据和所有筛选条件计算最终结果,同时缓存计算结果提升性能:
import { createSelector } from '@reduxjs/toolkit'; // 基础选择器,获取原始数据和筛选条件 const selectProducts = state => state.filter.products; const selectFilters = state => state.filter.filters; // 计算筛选结果的选择器 export const selectFilteredItems = createSelector( [selectProducts, selectFilters], (products, filters) => { return products.filter(item => { // 每个维度的筛选逻辑:如果是"All"则跳过,否则匹配对应字段 const matchesCategory = filters.category === "All" || item.category === filters.category; const matchesGender = filters.gender === "All" || item.gender === filters.gender; const matchesColor = filters.color === "All" || item.color === filters.color; const matchesBrand = filters.brand === "All" || item.brand === filters.brand; // 只有所有条件都满足的项才保留 return matchesCategory && matchesGender && matchesColor && matchesBrand; }); } );
组件中使用方式
在组件里通过useSelector获取最终筛选结果,用dispatch更新筛选条件:
import { useSelector, useDispatch } from 'react-redux'; import { selectFilteredItems, setCategoryFilter, setColorFilter } from './filterSlice'; function ProductList() { const filteredItems = useSelector(selectFilteredItems); const dispatch = useDispatch(); return ( <div> <select onChange={(e) => dispatch(setCategoryFilter(e.target.value))}> <option value="All">全部分类</option> <option value="Shoes">鞋子</option> {/* 其他分类选项 */} </select> <select onChange={(e) => dispatch(setColorFilter(e.target.value))}> <option value="All">所有颜色</option> <option value="Red">红色</option> {/* 其他颜色选项 */} </select> {/* 渲染filteredItems */} {filteredItems.map(item => ( <div key={item.id}>{item.name}</div> ))} </div> ); }
为什么这样能解决问题
- 所有筛选条件都被持久化保存,不会因为新的筛选操作丢失
- 每次筛选结果都是基于原始数据+所有筛选条件重新计算,自然实现了多条件联合筛选
createSelector会缓存计算结果,只有当原始数据或筛选条件变化时才重新计算,避免不必要的性能消耗
内容的提问来源于stack exchange,提问作者Kris
相关产品推荐
相关产品推荐

