React+Redux实现实时搜索时城市数据按名称过滤不生效如何解决
问题排查与修复方案
Action payload结构与Reducer取值不匹配
你在FilterCity的action里直接将搜索字符串q作为payload传入,但Reducer中尝试读取payload.name,此时payload.name为undefined,匹配逻辑永远不成立。
Reducer数组拼接逻辑错误
当前代码将initialState.myCities全量数据和过滤结果展开拼接,最终得到的是「全量数据+过滤后数据」的组合,完全没有实现过滤效果。同时不应该直接修改存储全量数据的字段,否则第一次过滤后就会丢失全量数据源,后续搜索无法正常执行,建议新增字段单独存储过滤结果,或者拆分全量数据、展示数据两个存储字段。
toString调用方式错误
代码中直接使用toString(item.name)不符合语法规范,应该调用值本身的toString方法:item.name.toString()。且完全相等的匹配规则过于严格,建议改为模糊匹配同时统一大小写,优化搜索体验。
冗余的async声明
FilterCity的action中没有任何异步逻辑,不需要加async声明,虽不是直接导致问题的原因,但属于冗余代码。
修正后的代码示例
Action 代码
// 移除多余的async声明 export const FilterCity = (q) => (dispatch) => { dispatch({ type: ActionTypes.GETBY_MYLIST, payload: q, }); };
Reducer 代码
// 初始state调整,拆分全量数据和展示数据 const initialState = { allCities: [], // 存储全量城市数据,过滤时作为数据源,不会被修改 myCities: [], // 存储当前要展示的过滤后城市数据 // 其余原有字段保持不变 } // 过滤逻辑调整 case ActionTypes.GETBY_MYLIST: const searchKey = payload.trim().toLowerCase(); return { ...state, myCities: searchKey === '' ? [...state.allCities] // 搜索词为空时展示全部城市 : state.allCities.filter(item => item.name.toString().toLowerCase().includes(searchKey) ) }; // 注意FetchCityData请求成功后要同时更新两个字段 case ActionTypes.FETCH_CITY_SUCCESS: return { ...state, allCities: [...payload], myCities: [...payload] }
组件逻辑优化(可选)
增加防抖避免输入过程中频繁触发过滤逻辑:
const dispatch = useDispatch(); const [input, setInput] = useState(""); useEffect(() => { // 300ms无输入再触发搜索 const timer = setTimeout(() => { dispatch(FilterCity(input)); }, 300) return () => clearTimeout(timer) }, [input, dispatch]); const HandleRefresh = () => { dispatch(FetchCityData()); };
内容的提问来源于stack exchange,提问作者Ceren Keklik
相关产品推荐
相关产品推荐

