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

React中输入框与下拉框过滤数组异常:全量展示时报错

React数组筛选报错问题解决

问题描述

在React项目中实现输入框搜索国家名、下拉框筛选地区的功能,输入框和指定地区筛选正常,但选择「全部地区」时抛出错误:Uncaught TypeError: Cannot convert undefined or null to object。

现有代码

  1. useState初始化:
const [inputData, setInputData] = useState([""]);
const [optionsData, setOptionsData] = useState(["europe"]);
  1. 输入框与下拉框JSX:
<div>
  <input
    className="search_country_input"
    type="text"
    name="countryInput"
    placeholder="Search for a country..."
    onChange={(event) => {
      setInputData(event.target.value);
    }}
  />
  <select
    className="options_select"
    name="regions"
    id="region"
    onChange={(event) => {
      setOptionsData(event.target.value);
    }}
  >
    <option value="">All regions</option>
    <option value="Europe">Europe</option>
    <option value="Asia">Asia</option>
    <option value="Africa">Africa</option>
    <option value="Americas">Americas</option>
    <option value="Oceania">Oceania</option>
  </select>
</div>
  1. 筛选逻辑:
fetchedData
  .filter((item) => {
    if (
      inputData !== "" &&
      item.name.common
        .toString()
        .toUpperCase()
        .includes(inputData.toString().toUpperCase())
    ) {
      return item;
    } else if (inputData === "") return item;
    return false;
  })
  .filter((item) => {
    if (
      optionsData !== "" &&
      item.region
        .toString()
        .toUpperCase()
        .includes(optionsData.toString().toUpperCase())
    ) {
      return item;
    } else if (optionsData === "") return item;
    return false;
  })

问题根源

  1. useState初始值类型错误:输入框和下拉框的取值都是字符串,但初始时把inputData和optionsData设成了数组,导致初始渲染时类型不匹配,判断条件失效。
  2. 未处理空值字段:fetchedData中部分项的region字段为undefined或null,直接调用toString()会触发类型错误;选择「全部地区」时这些空值项会被保留,若后续渲染中对region执行对象操作(比如Object.keys()),也会抛出错误。
  3. 筛选逻辑冗余且不严谨:两次filter遍历效率低,且未对字段做安全校验。

解决方案

1. 修正useState初始值

将初始值改为字符串类型,与输入框/下拉框的取值类型一致:

const [inputData, setInputData] = useState("");
const [optionsData, setOptionsData] = useState("europe");

2. 优化筛选逻辑(合并+空值校验)

合并两次filter为一次,同时用可选链?.和空值合并??处理字段为空的情况,避免报错:

const filteredData = fetchedData.filter((item) => {
  // 输入框筛选:空输入直接通过,否则检查国家名匹配
  const matchesInput = inputData === "" 
    ? true 
    : (item.name?.common?.toString().toUpperCase().includes(inputData.toUpperCase()) ?? false);

  // 地区筛选:选全部地区直接通过,否则检查地区匹配
  const matchesRegion = optionsData === "" 
    ? true 
    : (item.region?.toString().toUpperCase().includes(optionsData.toUpperCase()) ?? false);

  // 两个条件都满足才保留
  return matchesInput && matchesRegion;
});

3. 渲染时处理空值字段

如果渲染region时需要执行对象操作,先做空值判断:

{filteredData.map(item => (
  <div key={item.name.common}>
    <p>国家:{item.name.common}</p>
    <p>地区:{item.region ?? "未知"}</p>
    {/* 若需处理region的子字段,比如subregion */}
    <p>子地区:{item.subregion ?? "无"}</p>
  </div>
))}

验证效果

修改后,选择「全部地区」时会正确保留所有符合输入框条件的项,同时避免空值字段引发的类型错误,输入框和地区筛选功能正常。

内容的提问来源于stack exchange,提问作者G010

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 16:25:14