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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 18:06:04