使用Redux Toolkit实现通知筛选的问题及正确性咨询
问题分析与解决方案
当前实现的问题
- 无法基于全量数据搜索:每次调用
filterNotices时直接修改state.notices为过滤后的结果,导致原始全量通知数据被覆盖。后续搜索只能基于上次过滤后的子集执行,无法遍历所有通知。 - Advanced模式标签判断逻辑错误:使用
note.tags.filter(...)作为判断条件,filter返回匹配的标签数组,即使无匹配项,空数组在JS中属于真值(Boolean([]) === true),会导致该条件始终为真,无法正确过滤标签。
修复方案
- 保存原始全量数据:在state中新增
originalNotices字段,专门存储从接口获取的所有通知,确保每次搜索都基于全量数据执行。 - 基于原始数据过滤:
filterNotices逻辑中从originalNotices取数进行过滤,将结果赋值给notices用于页面展示。 - 修正标签判断逻辑:将
filter替换为some,some会在数组存在任意匹配元素时返回true,否则返回false,符合标签匹配的判断需求。
修改后的完整代码
import { createSlice, createAsyncThunk } from "@reduxjs/toolkit"; import axios from "axios"; const url = "http://localhost:8000/"; const initialState = { notices: [], originalNotices: [], // 新增:存储原始全量通知 }; export const getNotices = createAsyncThunk( "notices/getNotices", async (_name, thunkAPI) => { try { const resp = await axios(`${url}notices`); return resp.data; } catch (error) { return thunkAPI.rejectWithValue("something went wrong"); } } ); const noticesSlice = createSlice({ name: "notices", initialState, reducers: { filterNotices: (state, { payload }) => { const { search, searchOption } = payload; const lowerSearch = search.toLowerCase(); if (searchOption === "Simple") { state.notices = state.originalNotices.filter((note) => note.title.toLowerCase().includes(lowerSearch) ); } else if (searchOption === "Advanced") { state.notices = state.originalNotices.filter((note) => note.description.toLowerCase().includes(lowerSearch) || note.tags.some((tag) => tag.toLowerCase().includes(lowerSearch)) ); } // 可选:添加清空搜索的逻辑,比如search为空时恢复显示所有通知 // if (!search) state.notices = state.originalNotices; }, }, extraReducers: (builder) => { builder .addCase(getNotices.fulfilled, (state, { payload }) => { state.notices = payload; state.originalNotices = payload; // 同步保存原始全量数据 }) }, }); export const { filterNotices } = noticesSlice.actions; export default noticesSlice.reducer;
内容的提问来源于stack exchange,提问作者SerbianDeveloper
相关产品推荐
相关产品推荐

