React Hook useState处理API JSON数据失效,出现undefined属性读取错误
问题分析与解决方案
错误原因
- 初始渲染空值访问:组件首次渲染时,
anime是初始的空数组,anime[0]为undefined,传给MovieCard后直接访问M1.ranking触发TypeError。 - API请求逻辑错误:
searchAnime函数中,使用await response.json()已经获取了解析后的JSON对象,多余的.then()调用导致setAnime从未被正确执行,anime始终是空数组。
修复步骤
1. 修正API请求逻辑
修改searchAnime函数,移除无效的.then()调用,直接处理解析后的数据:
const searchAnime = async (title) => { const response = await fetch(`${API_URL}&search=${title}`, options); const data = await response.json(); // 直接将API返回的data数组存入状态 setAnime(data.data); };
2. 避免空值访问错误
有两种方案可选:
方案一:父组件条件渲染
在App组件中,仅当anime数组有内容时才渲染MovieCard:
<div className="container"> {anime.length > 0 && <MovieCard M1={anime[0]} />} </div>
方案二:子组件空值校验
在MovieCard组件中先判断M1是否存在,再访问其属性:
const MovieCard = ({ M1 }) => { // 若M1未定义,返回空或加载提示 if (!M1) return <div>Loading...</div>; return ( <div className="movie"> <div> <p>Current Ranking: {M1.ranking}</p> </div> <div> <img src={M1.image} alt={M1.title} /> </div> <div> <span>{M1.type}</span> <h3>{M1.title}</h3> </div> </div> ); };
3. 可选:添加加载状态优化体验
增加加载状态提示,让用户感知数据请求过程:
const App = () => { const [anime, setAnime] = useState([]); const [loading, setLoading] = useState(true); const searchAnime = async (title) => { setLoading(true); try { const response = await fetch(`${API_URL}&search=${title}`, options); const data = await response.json(); setAnime(data.data); } catch (err) { console.error('请求失败:', err); } finally { setLoading(false); } }; useEffect(() => { searchAnime("shigatsu"); }, []); return ( <div className="app"> <h1>Annie-Plex</h1> <div className="search"> <input placeholder="Search for Anime" value="" onChange={() => {}} /> <img src={SearchIcon} alt="Search" onClick={() => {}} /> </div> <div className="container"> {loading ? ( <div>Loading...</div> ) : ( anime.length > 0 && <MovieCard M1={anime[0]} /> )} </div> </div> ); };
内容的提问来源于stack exchange,提问作者Eeshaan
相关产品推荐
相关产品推荐

