React前端优雅实现过滤:无需多状态副本与Redux方案探讨
优雅实现React食谱过滤方案
核心原则:始终基于原始数据做多层过滤
不用保存中间过滤结果,每次过滤都从**原始食谱列表(recipes)**出发,依次叠加所有过滤条件(分类、菜系、搜索关键词),这样就不需要维护多份状态副本,逻辑更清晰。
具体实现步骤
- 拆分过滤逻辑为独立函数
把不同过滤条件拆成单独的纯函数,可读性和可维护性更强:
// 分类过滤 const filterByCategory = (recipe: IRecipe, categories: string[]) => { return categories.length === 0 || categories.includes(recipe.strCategory); }; // 菜系过滤 const filterByCuisine = (recipe: IRecipe, cuisines: string[]) => { return cuisines.length === 0 || cuisines.includes(recipe.strArea); }; // 搜索过滤(支持标题、描述等字段) const filterBySearch = (recipe: IRecipe, searchTerm: string) => { const lowerTerm = searchTerm.toLowerCase(); return ( recipe.strMeal.toLowerCase().includes(lowerTerm) || recipe.strInstructions.toLowerCase().includes(lowerTerm) // 可按需扩展到食材、标签等其他字段 ); };
- 链式调用过滤函数
在组件中基于原始recipes依次应用所有过滤条件,得到最终展示的列表:
// 假设你的状态包含:filters(Categories、Cousines)、searchTerm const shownRecipes = recipes .filter(recipe => filterByCategory(recipe, filters.Categories)) .filter(recipe => filterByCuisine(recipe, filters.Cousines)) .filter(recipe => filterBySearch(recipe, searchTerm));
不管后续新增多少过滤条件,只需要追加filter调用即可,彻底告别嵌套的if-else逻辑。
- 状态管理:本地状态足够解决问题
当前场景下用React原生useState完全够用:
- 用
useState分别保存filters(分类、菜系的选中集合)和searchTerm(搜索关键词) - 每次状态更新时,React会自动重新计算
shownRecipes并渲染最新结果
关于Redux的useSelector
如果后续项目复杂度提升(比如多个组件需要共享食谱数据或过滤状态),可以考虑引入Redux:
- 将原始食谱列表存入Redux store
- 用
useSelector从store中获取原始数据和过滤条件,在selector内完成过滤计算 - 优势是过滤逻辑可复用,多组件能同步获取最新过滤结果
但当前阶段完全不需要Redux,本地状态已经能优雅解决问题,过度引入反而增加不必要的复杂度。
内容的提问来源于stack exchange,提问作者Dusan Stojanovic
相关产品推荐
相关产品推荐

