React中输入框与下拉框过滤数组异常:全量展示时报错
React数组筛选报错问题解决
问题描述
在React项目中实现输入框搜索国家名、下拉框筛选地区的功能,输入框和指定地区筛选正常,但选择「全部地区」时抛出错误:Uncaught TypeError: Cannot convert undefined or null to object。
现有代码
- useState初始化:
const [inputData, setInputData] = useState([""]); const [optionsData, setOptionsData] = useState(["europe"]);
- 输入框与下拉框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>
- 筛选逻辑:
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; })
问题根源
- useState初始值类型错误:输入框和下拉框的取值都是字符串,但初始时把
inputData和optionsData设成了数组,导致初始渲染时类型不匹配,判断条件失效。 - 未处理空值字段:
fetchedData中部分项的region字段为undefined或null,直接调用toString()会触发类型错误;选择「全部地区」时这些空值项会被保留,若后续渲染中对region执行对象操作(比如Object.keys()),也会抛出错误。 - 筛选逻辑冗余且不严谨:两次
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
相关产品推荐
相关产品推荐

