React报错:Cannot read properties of undefined (reading 'filter') 求助
解决React应用搜索时的filter报错问题
报错Uncaught TypeError: Cannot read properties of undefined (reading 'filter')的核心原因是调用filter方法时,countryList的值为undefined,以下是具体问题点和修复方案:
问题1:初始状态未初始化数组
countryList的初始状态未设置默认值,默认是undefined。在axios请求完成前,如果用户触发搜索,就会对undefined调用filter方法导致报错。
修复:给countryList初始化为空数组
const [countryList, setCountryList] = useState([]);
问题2:未处理数据加载前的交互
即使初始化为空数组,也需要在数据加载完成前避免无效的搜索逻辑,同时给用户加载提示。新增loading状态:
const [loading, setLoading] = useState(true); useEffect(() => { axios .get("https://restcountries.com/v3.1/all") .then((res) => { setCountryList(res.data); setLoading(false); // 请求完成标记加载结束 }) .catch(err => { console.error(err); setLoading(false); // 请求失败也标记加载结束 }); }, []);
在渲染最外层先判断加载状态:
if (loading) { return <div>加载中...</div>; }
问题3:搜索逻辑存在漏洞
原onSearch仅匹配单个空格,用户输入空字符串或全空格时逻辑失效,且状态更新顺序可能导致不同步。
修复:
const onSearch = (event) => { const value = event.target.value.trim(); // 去除首尾空格 if (!value) { // 空字符串或全空格时重置状态 setFilter(false); setSearch(""); } else { setFilter(true); setSearch(value); } };
问题4:countriesList计算逻辑不严谨
原逻辑中filter为false时返回null,后续判断length会报错;且搜索未忽略大小写,用户体验差。
修复:
const countriesList = filter ? countryList.filter((country) => // 忽略大小写匹配,提升搜索友好度 country.name.common.toLowerCase().includes(search.toLowerCase()) ) : []; // 改为空数组避免length判断报错
问题5:渲染逻辑的冗余代码
原代码中&& console.log会导致React渲染undefined,不符合规范,移除并改用useEffect监听打印:
// 在组件内新增 useEffect(() => { if (filter && countriesList.length === 1) { console.log("common", countriesList); } }, [filter, countriesList]);
同时修改渲染分支的else块:
<Country name={countriesList[0].name.common} num={true} />
修复后完整App组件代码
import { useState, useEffect } from "react"; import axios from "axios"; import Input from "./components/Input"; import Country from "./components/Country"; const App = () => { const [countryList, setCountryList] = useState([]); const [search, setSearch] = useState(""); const [filter, setFilter] = useState(false); const [loading, setLoading] = useState(true); useEffect(() => { axios .get("https://restcountries.com/v3.1/all") .then((res) => { setCountryList(res.data); setLoading(false); }) .catch(err => { console.error(err); setLoading(false); }); }, []); const onSearch = (event) => { const value = event.target.value.trim(); if (!value) { setFilter(false); setSearch(""); } else { setFilter(true); setSearch(value); } }; const countriesList = filter ? countryList.filter((country) => country.name.common.toLowerCase().includes(search.toLowerCase()) ) : []; useEffect(() => { if (filter && countriesList.length === 1) { console.log("common", countriesList); } }, [filter, countriesList]); if (loading) { return <div>加载中...</div>; } return ( <div> <Input onSearch={onSearch} search={search} /> {filter ? ( countriesList.length === 0 ? ( <h3>No match</h3> ) : countriesList.length > 10 ? ( <h3>Too many matches, specify another filter...</h3> ) : countriesList.length < 10 && countriesList.length > 1 ? ( countriesList.map((country, i) => ( <Country name={country.name.common} key={i} num={false} /> )) ) : ( <Country name={countriesList[0].name.common} num={true} /> ) ) : ( <h3>Search for any country</h3> )} </div> ); }; export default App;
内容的提问来源于stack exchange,提问作者Yovel Hadad
相关产品推荐
相关产品推荐

